15.3.22湖南省多校对抗
http://acm.csu.edu.cn/OnlineJudge/contest.php?cid=2070
比赛是组队赛,居然弄了一个第三名,现场第二,醉了
多亏队友们的齐心协力,全部1A,出的题不是最多但是比较快没有罚时~
赛后自己把题目又重新A了一遍。
A:CSU1536N比较小,直接暴力搜索一遍
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1010; 36 const int MAXM = 2000010; 37 const double eps = 1e-4; 38 39 int n, m; 40 struct Node { 41 int arr[16], step; 42 }s; 43 int tar[20], vis[1 << 16]; 44 45 int conv(Node a) { 46 int ret = 0; 47 rep (i, 0, n - 1) { 48 ret <<= 1; 49 ret |= a.arr[i]; 50 } 51 return ret; 52 } 53 54 int getEnd(Node a) { 55 int cnt = 1, id = 0; 56 rep (i, 1, n - 1) { 57 if(a.arr[i] == a.arr[i - 1]) cnt ++; 58 else { 59 if(cnt != tar[id]) return 0; 60 cnt = 1; id ++; 61 } 62 } 63 return cnt == tar[id]; 64 } 65 66 int bfs() 67 { 68 mem0(vis); 69 queue<Node>q; 70 s.step = 0; 71 vis[conv(s)] = 1; 72 q.push(s); 73 while(!q.empty()) { 74 Node fr = q.front(); q.pop(); 75 if(getEnd(fr)) return fr.step; 76 rep (i, 0, n - 2) { 77 Node tail = fr; 78 swap(tail.arr[i], tail.arr[i + 1]); 79 if(!vis[conv(tail)]) { 80 tail.step = fr.step + 1; 81 q.push(tail); 82 vis[conv(tail)] = 1; 83 } 84 } 85 } 86 return 0; 87 } 88 89 int main() 90 { 91 //FIN; 92 while(~scanf("%d %d", &n, &m)) { 93 rep (i, 0, n - 1) scanf("%d", &s.arr[i]); 94 rep (i, 0, m - 1) scanf("%d", &tar[i]); 95 cout << bfs() << endl; 96 } 97 return 0; 98 }
B:CSU1537模拟一遍
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i +=2) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1010; 36 const int MAXM = 2000010; 37 const double eps = 1e-4; 38 39 char s[200]; 40 int res; 41 42 int equals1() { 43 stack<int>st; 44 st.push(s[0] - '0'); 45 int len = strlen(s); 46 rep (i, 1, len-1) { 47 if(s[i] == '+') st.push(s[i + 1] - '0'); 48 else st.top() = st.top() * (s[i + 1] - '0'); 49 } 50 int ret = 0; 51 while(!st.empty()) { 52 ret += st.top(); st.pop(); 53 } 54 return ret == res; 55 } 56 57 int equals2() { 58 int len = strlen(s), ret = s[0] - '0'; 59 rep (i, 1, len-1) { 60 if(s[i] == '+') ret += s[i + 1] - '0'; 61 else ret *= s[i + 1] - '0'; 62 } 63 return ret == res; 64 } 65 66 int main() 67 { 68 //FIN; 69 while(cin >> s >> res) { 70 int ans1 = equals1(), ans2 = equals2(); 71 if(ans1) { 72 if(ans2) puts("U"); 73 else puts("M"); 74 } 75 else { 76 if(ans2) puts("L"); 77 else puts("I"); 78 } 79 } 80 return 0; 81 }
C:CSU1538分析一遍发现要走最少的路程,应该如果有交叉的区间,直接合并为一个大的区间,即若(a1, b1)与(a2, b2)满足a1 < a2,若a2 <= b1那么将其合并为(a1, b2)即应从a1走到b2再回到a1(这时就访问了b1与a2),再去到b2,证明也是可以证明的。
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1010; 36 const int MAXM = 2000010; 37 const double eps = 1e-4; 38 39 struct Node { 40 int l, r; 41 bool operator < (const Node& A) const { 42 return l < A.l; 43 } 44 }l[10000]; 45 int n, m; 46 47 int main() 48 { 49 //FIN; 50 while(cin >> n >> m) { 51 mem0(l); 52 rep (i, 0, m - 1) { 53 scanf("%d %d", &l[i].l, &l[i].r); 54 } 55 sort(l, l + m); 56 int ans = n + 1, maxr = l[0].r, curl = l[0].l; 57 rep (i, 1, m - 1) { 58 if(l[i].l > maxr) { 59 ans += 2 * (maxr - curl); 60 curl = l[i].l; 61 maxr = l[i].r; 62 } 63 else maxr = max(l[i].r, maxr); 64 } 65 ans += 2 * (maxr - curl); 66 cout << ans << endl; 67 } 68 return 0; 69 }
D:CSU1539直接二分答案,通过V是可以算出是否可以通过每个杆的(这里还需要枚举反弹的次数,反正次数不多)。这里先贴上队友比赛时的代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <queue> 5 #include <algorithm> 6 #include <stack> 7 #include <cmath> 8 using namespace std; 9 #define mem0(a) memset(a, 0, sizeof(a)) 10 11 const double eps = 1e-6; 12 const double maxans = 1e6; 13 const double pi = 3.14159265359; 14 double d, p[20], h[20]; 15 int n, b; 16 double calc(double x, double vx, double vy) { 17 double a = -1.0 / 2 / vx / vx, b = vy / vx; 18 return a * x * x + b * x; 19 } 20 bool Check(double v, int total) { 21 double dd = d / total, sumd = 0, tt = dd / v / v; 22 if (tt >= 1) return 0; 23 double sita = asin(tt) / 2; 24 sita = max(sita, pi / 2 - sita); 25 double vx = v * cos(sita), vy = v * sin(sita); 26 int now = 0; 27 for (int i = 0; i < total; i++) { 28 while (p[now] > sumd && p[now] < sumd + dd) { 29 double x0 = p[now] - sumd; 30 if (calc(x0, vx, vy) < h[now]) return 0; 31 now++; 32 } 33 sumd += dd; 34 } 35 return 1; 36 } 37 double work(int total) { 38 double l = 0.000001, r = maxans; 39 while (fabs(r - l) > eps) { 40 double m = (l + r) / 2; 41 if (Check(m, total)) r = m; 42 else l = m; 43 } 44 return l; 45 } 46 bool Conflict(int t) { 47 for (int i = 0; i < t; i++) { 48 double tmp = d / (t + 1) * (i + 1); 49 for (int j = 0; j < n; j++) { 50 if (fabs(p[j] - tmp) < eps) return 1; 51 } 52 } 53 return 0; 54 } 55 int main() 56 { 57 //freopen("in.txt", "r", stdin); 58 while(cin >> d >> n >> b) { 59 for (int i = 0; i < n; i++) { 60 cin >> p[i] >> h[i]; 61 } 62 double ans = maxans; 63 for (int i = 0; i <= b; i++) { 64 if (Conflict(i)) continue; 65 ans = min(ans, work(i + 1)); 66 } 67 printf("%.5f\n", ans); 68 } 69 return 0; 70 }
E:CSU1540赛后花了比较多的时间去A掉这道题,看懂题花了比较大的精力,A掉他花了更大的精力,这里就讲讲题目意思吧:
题目意思是说一辆车从起点开始随机到处乱走,现在知道的条件只有它从i - 1时刻到i时刻走了距离p,且i时刻GPS测出来的前进方向是d方向(E, W, N, S),问在最后的t时刻这辆车会停留在哪些位置。另外一个条件就是说若 k 时刻这辆车正在一个拐弯处,那么GPS测出来的时间可能是转弯前的方向,也有可能是转弯后的方向。
注意看数据范围 x , y <= 50 这时候我想你们知道该怎么做了= =(dfs+状态标记。。)
调试的我想死啊。。。
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> int CMP_MIN(T a, T b) { return a < b; } 27 template<class T> int CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1010; 36 const int MAXM = 20010; 37 const double eps = 1e-4; 38 39 const int dx[4] = {0, -1, 0, 1}; 40 const int dy[4] = {1, 0, -1, 0}; 41 char pas[5] = {"NWSE"}; 42 int DN = 0, DS = 2, DE = 3, DW = 1; 43 44 struct Point { 45 int x, y, d; 46 Point(){} 47 Point(int _x, int _y, int _d){ 48 x = _x; y = _y, d = _d; 49 } 50 bool operator < (Point& A) const { 51 return x != A.x ? x < A.x : y < A.y; 52 } 53 }st, q[2][3000]; 54 struct Line { 55 Point u, v; 56 }v[100], h[100], tmp; 57 int cnt[2], n, t, vcnt, hcnt, e[60][60][5]; 58 bool vis[55][55][4][20]; 59 60 void addEdge() { 61 mem0(e); 62 rep (i, 0, vcnt - 1) rep (j, 0, hcnt - 1) { 63 if(h[j].u.y < v[i].u.y || h[j].u.y > v[i].v.y 64 || v[i].u.x < h[j].u.x || v[i].u.x > h[j].v.x) continue; 65 int fo[4] = {0}; 66 if(v[i].v.y == h[j].u.y) fo[0] = 1; 67 if(v[i].u.x == h[j].u.x) fo[1] = 1; 68 if(v[i].u.y == h[j].u.y) fo[2] = 1; 69 if(v[i].u.x == h[j].v.x) fo[3] = 1; 70 rep (k, 0, 3) if(!fo[k]) { 71 e[v[i].u.x][h[j].u.y][k] = 1; 72 } 73 } 74 rep (i, 0, vcnt - 1) { 75 int curx = v[i].u.x, miny = v[i].u.y, maxy = v[i].v.y; 76 rep (j, miny, maxy) { 77 if(j < maxy) e[curx][j][DN] = 1; 78 if(j > miny) e[curx][j][DS] = 1; 79 } 80 } 81 rep (i, 0, hcnt - 1) { 82 int minx = h[i].u.x, maxx = h[i].v.x, cury = h[i].u.y; 83 rep (j, minx, maxx) { 84 if(j < maxx) e[j][cury][DE] = 1; 85 if(j > minx) e[j][cury][DW] = 1; 86 } 87 } 88 } 89 90 int check(int x, int y, int od, int d, int s) 91 { 92 int isN = e[x][y][DN], isS = e[x][y][DS], isE = e[x][y][DE], isW = e[x][y][DW]; 93 int sum = isN + isS + isW + isE; 94 if(sum == 4) { 95 if(od == s) return d != (s + 2) % 4; 96 return d == s; 97 } 98 if(sum == 3){ 99 return s != od ? d == s : 1; 100 } 101 if(sum == 2) { 102 if(isN&&isS || isE&&isW) return s == d && d == od; 103 int a = isN ? DN : DS, b = isE ? DE : DW; 104 if((a + 2) % 4 == od) return (s == od || s == b) && d == b; 105 if((b + 2) % 4 == od) return (s == od || s == a) && d == a; 106 } 107 return 1; 108 } 109 110 void dfs(int x, int y, int odir, int dir, int seems, int now, int s) 111 { 112 if(s == 0) { 113 if(check(x, y, odir, dir, seems)) { 114 q[now][cnt[now]++] = Point(x, y, dir); 115 } 116 return ; 117 } 118 if(vis[x][y][dir][s]) return ; 119 vis[x][y][dir][s] = 1; 120 x += dx[dir]; y += dy[dir]; 121 rep (i, 0, 3) if(e[x][y][i] && (i + 2) % 4 != dir) { 122 dfs(x, y, dir, i, seems, now, s - 1); 123 } 124 } 125 126 int conv(char ch) { 127 if(ch == 'N') return DN; 128 if(ch == 'S') return DS; 129 if(ch == 'E') return DE; 130 return DW; 131 } 132 133 int cmp(Point a, Point b) { 134 return a < b; 135 } 136 137 int main() 138 { 139 140 while(~scanf("%d %d %d %d", &n, &st.x, &st.y, &t)) { 141 vcnt = hcnt = 0; 142 mem0(cnt); 143 rep (i, 0, n - 1) { 144 scanf("%d %d %d %d", &tmp.u.x, &tmp.u.y, &tmp.v.x, &tmp.v.y); 145 if(tmp.u.x > tmp.v.x) swap(tmp.u.x, tmp.v.x); 146 if(tmp.u. y > tmp.v.y) swap(tmp.u.y, tmp.v.y); 147 if(tmp.u.x == tmp.v.x) v[vcnt++] = tmp; 148 else h[hcnt++] = tmp; 149 //printf("%d %d %d %d\n", tmp.u.x, tmp.u.y, tmp.v.x, tmp.v.y); 150 } 151 addEdge(); 152 int now = 0, step = 0; char dir; 153 rep (i, 0, 3) if(e[st.x][st.y][i]) { 154 q[now][cnt[now]++] = Point(st.x, st.y, i); 155 } 156 rep (i, 0, t - 1) { 157 scanf("%d %c", &step, &dir); 158 now = !now; mem0(vis); cnt[now] = 0; 159 rep (j, 0, cnt[!now] - 1) { 160 dfs(q[!now][j].x, q[!now][j].y, -1, q[!now][j].d, conv(dir), now, step); 161 } 162 } 163 sort(q[now], q[now] + cnt[now], cmp); 164 int lax = -1, lay = -1; 165 rep (i, 0, cnt[now] - 1) if(q[now][i].x != lax || q[now][i].y != lay) { 166 printf("%d %d\n", q[now][i].x, q[now][i].y); 167 lax = q[now][i].x; 168 lay = q[now][i].y; 169 } 170 } 171 return 0; 172 }
F:CSU1541题目大意就是给一个图,问为了构建最先生成树,哪些边是不可被替代的,(不可被替代就是说如果这条边被删除,最小生成树的权值会变大)
上面已经说了如果被删除权值会变大就是不可替代的,所以先求一遍最小生成树,然后枚举最小生成树的边,删除看最小生成树权值是否变大,或图是否还连通,这样复杂度就是O(m * logm) + O(m * n),正好可以过
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1010; 36 const int MAXM = 2000010; 37 const double eps = 1e-4; 38 39 struct Edge { 40 int u, v, w; 41 bool operator < (const Edge& A) const { 42 return w < A.w; 43 } 44 }e[51000]; 45 46 int minE[51000], cnt, fa[510], n, m; 47 48 int findP(int x) { return x == fa[x] ? x : fa[x] = findP(fa[x]); } 49 50 int kruskal(int forbidon) { 51 int ret = 0, num = n - 1; 52 rep (i, 0, n) fa[i] = i; 53 rep (i, 0, m - 1) if(i != forbidon) { 54 int x = findP(e[i].u), y = findP(e[i].v); 55 if(x != y) { 56 ret += e[i].w; 57 fa[x] = y; 58 if(forbidon < 0) minE[cnt++] = i; 59 num --; 60 } 61 } 62 return ret = num ? INF : ret; 63 } 64 65 int main() 66 { 67 //FIN; 68 while(cin >> n >> m) { 69 rep (i, 0, m - 1) scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w); 70 sort(e, e + m); 71 cnt = 0; 72 int minW = kruskal(-1); 73 int num = 0, sum = 0; 74 rep (i, 0, cnt - 1) { 75 if(kruskal(minE[i]) > minW) num ++, sum += e[minE[i]].w; 76 } 77 cout << num << " " << sum << endl; 78 } 79 return 0; 80 }
G:题目是说一个原始匹配的括号序列,每次将位置p的括号反转,问最左侧需要将哪个括号反转使得括号序列重新获得匹配。
结题报告:http://www.cnblogs.com/gj-Acit/p/4361520.html
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf (-((LL)1<<40)) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FIN freopen("in.txt", "r", stdin) 23 #define FOUT freopen("out.txt", "w", stdout) 24 #define rep(i, a, b) for(int i = a; i <= b; i ++) 25 26 template<class T> T CMP_MIN(T a, T b) { return a < b; } 27 template<class T> T CMP_MAX(T a, T b) { return a > b; } 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 1010; 36 const int MAXM = 20010; 37 const double eps = 1e-4; 38 39 int n, q, p, len; 40 char s[310000]={"1"}; 41 struct Node { 42 int f, a, s; 43 }t[310000<<2]; 44 45 char rev(char c) { return (c == '(') ? ')' : '('; } 46 47 void buildTree(int k, int L, int R, int p, int a) 48 { 49 t[k].s = 0; 50 if(L == R) { 51 t[k].f = a - L; t[k].a = a; 52 return ; 53 } 54 int mid = (L + R) >> 1; 55 if(p > mid) buildTree(rson, p, a); 56 else buildTree(lson, p, a); 57 t[k].f = min(t[k<<1].f, t[k<<1|1].f); 58 t[k].a = min(t[k<<1].a, t[k<<1|1].a); 59 } 60 61 void init() 62 { 63 mem0(t); 64 int sum = 0; 65 len = strlen(s) - 1; 66 rep (i, 1, len) { 67 sum += (s[i] == '(') ? 1 : -1; 68 buildTree(1, 1, len, i, sum);//建树 69 } 70 } 71 72 //向下传延时标记 73 void pushDown(int k) 74 { 75 t[k<<1].s += t[k].s; t[k<<1].a += t[k].s; t[k<<1].f += t[k].s; 76 t[k<<1|1].s += t[k].s; t[k<<1|1].a += t[k].s; t[k<<1|1].f += t[k].s; 77 t[k].s = 0; 78 } 79 80 //更新操作,将区间[p, len]的所有值都+val 81 void update(int k, int L, int R, int p, int val) 82 { 83 if(p <= L) { 84 t[k].s += val; 85 t[k].a += val; 86 t[k].f += val; 87 return ; 88 } 89 pushDown(k); 90 int mid = (L + R) >> 1; 91 if(p <= mid) update(lson, p, val);//左侧可能需要更新 92 update(rson, p, val);//右侧是一定要更新的,因为需要更新的区间为[p, len] 93 t[k].f = min(t[k<<1].f, t[k<<1|1].f); 94 t[k].a = min(t[k<<1].a, t[k<<1|1].a); 95 } 96 97 //查询最左侧的右括号 98 int query1(int k, int L, int R) 99 { 100 if(L == R) return L; 101 int mid = (L + R) >> 1; 102 pushDown(k); 103 if(t[k<<1].f < 0) return query1(lson); 104 return query1(rson); 105 } 106 107 //查询从len往前连续的最长的满足a>=2的点,也就是最后一个<2的位置+1 108 int query2(int k, int L, int R) 109 { 110 if(L == R) return min(len, L + 1); 111 int mid = (L + R) >> 1; 112 pushDown(k); 113 if(t[k<<1|1].a < 2) return query2(rson); 114 return query2(lson); 115 } 116 117 int main() 118 { 119 //FIN; 120 while(~scanf("%d %d%*c %s", &n, &q, s + 1)) { 121 init(); 122 rep (i, 0, q - 1) { 123 scanf("%d", &p); 124 s[p] = rev(s[p]); update(1, 1, len, p, s[p] == ')' ? -2 : 2); 125 if(s[p] == ')') p = query1(1, 1, len);//find first ) 126 else p = query2(1, 1, len); //find last < 2 127 s[p] = rev(s[p]); update(1, 1, len, p, s[p] == ')' ? -2 : 2); 128 printf("%d\n", p); 129 } 130 } 131 return 0; 132 }