-
Notifications
You must be signed in to change notification settings - Fork 6
/
Brackets.cpp
93 lines (84 loc) · 2.26 KB
/
Brackets.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <cstdio>
#include <string>
using namespace std;
#define SIZE 30000
typedef struct Node { int open, close; } Node;
class SegmentTree {
Node tree[4*SIZE];
int parents[SIZE], size;
string elements;
Node mergeNodes(Node a, Node b) {
Node res;
int change = std::min(a.open, b.close);
res.open = a.open + b.open - change;
res.close = a.close + b.close - change;
return res;
}
public:
SegmentTree(string arr) : size(arr.length()) {
elements = arr;
buildTree(0, 0, size-1);
}
void buildTree(int curNode, int start, int end) {
if(start == end) {
tree[curNode].open = (elements[start] == ')' ? 0 : 1);
tree[curNode].close = (elements[start] == ')' ? 1 : 0);
parents[start] = curNode;
}
else {
int l = curNode * 2 + 1;
int r = curNode * 2 + 2;
int mid = (start + end)/2;
buildTree(l, start, mid);
buildTree(r, mid+1, end);
tree[curNode] = mergeNodes(tree[l], tree[r]);
}
}
Node query(int curNode, int start, int end, int qx, int qy) {
if(qx == start && qy == end)
return tree[curNode];
int l = curNode*2 + 1;
int r = curNode*2 + 2;
int mid = (start+end)/2;
if(qy <= mid)
return query(l, start, mid, qx, qy);
else if(qx > mid)
return query(r, mid+1, end, qx, qy);
else
return mergeNodes(query(l, start, mid, qx, qy), query(r, mid+1, end, mid+1, qy));
}
void update(int x) {
int curNode = parents[x];
Node prevVal = tree[curNode];
tree[curNode].open = !(prevVal.open == 1);
tree[curNode].close = !(prevVal.close == 1);
curNode = (curNode-1)/2;
while(curNode > 0) {
tree[curNode] = mergeNodes(tree[2*curNode+1], tree[2*curNode+2]);
curNode = (curNode-1)/2;
}
tree[0] = mergeNodes(tree[1], tree[2]);
}
};
int main() {
int N, Q, nCase = 1;
while(scanf("%d", &N) == 1) {
char str[SIZE];
scanf("%s", str);
string curStr(str);
scanf("%d", &Q);
SegmentTree ss(curStr);
printf("Test %d:\n", nCase++);
while(Q--) {
int op;
scanf("%d", &op);
if(op == 0) {
Node res = ss.query(0, 0, N-1, 0, N-1);
printf("%s\n", (res.open == 0 && res.close == 0 ? "YES" : "NO"));
}
else
ss.update(op-1);
}
}
return 0;
}