http://poj.org/problem?id=3225
线段树,【区间更新,单点查询】。
题意很容易明白,开始的时候假设集合为空,然后通过一系列的操作后输出最终的集合是什么。
因为数据范围比较小,不用离散化。把每个端点和区间分离出来,然后构建线段树,线段树只标记每个结点的状态。每个操作其实可以看成是对区间异或或者对区间赋值,其中是怎么结合的看代码。异或的更新没写好,wa了两次,这是到现在还错的东西。。。囧!
代码如下:
View Code
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdlib> 5 6 using namespace std; 7 8 const int maxn = 132000; 9 bool status[maxn]; 10 11 #define lson l, m, rt << 1 12 #define rson m + 1, r, rt << 1 | 1 13 14 struct segTree { 15 bool sign[maxn << 2], lateSet[maxn << 2], lateRev[maxn << 2]; 16 17 void down(int rt) { 18 int ls = rt << 1, rs = rt << 1 | 1; 19 20 if (lateSet[rt]) { 21 lateSet[ls] = lateSet[rs] = true; 22 sign[ls] = sign[rs] = sign[rt]; 23 lateSet[rt] = lateRev[rt] = lateRev[ls] = lateRev[rs] = false; 24 } 25 if (lateRev[rt]) { 26 lateRev[ls] = !lateRev[ls]; 27 lateRev[rs] = !lateRev[rs]; 28 sign[ls] = !sign[ls]; 29 sign[rs] = !sign[rs]; 30 lateRev[rt] = false; 31 } 32 } 33 34 void build(int l, int r, int rt) { 35 sign[rt] = lateSet[rt] = lateRev[rt] = false; 36 if (l == r) { 37 return ; 38 } 39 int m = (l + r) >> 1; 40 41 build(lson); 42 build(rson); 43 } 44 45 void init() { 46 build(0, maxn - 1, 1); 47 } 48 49 void reverse(int L, int R, int l, int r, int rt) { 50 if (L <= l && r <= R) { 51 if (!lateSet[rt]) { 52 lateRev[rt] = !lateRev[rt]; 53 } 54 sign[rt] = !sign[rt]; 55 56 return ; 57 } 58 int m = (l + r) >> 1; 59 60 down(rt); 61 if (L <= m) { 62 reverse(L, R, lson); 63 } 64 if (m < R) { 65 reverse(L, R, rson); 66 } 67 } 68 69 void setSign(bool s, int L, int R, int l, int r, int rt) { 70 if (L <= l && r <= R) { 71 sign[rt] = s; 72 lateSet[rt] = true; 73 lateRev[rt] = false; 74 75 return ; 76 } 77 int m = (l + r) >> 1; 78 79 down(rt); 80 if (L <= m) { 81 setSign(s, L, R, lson); 82 } 83 if (m < R) { 84 setSign(s, L, R, rson); 85 } 86 } 87 88 void opU(int L, int R) { 89 setSign(true, L, R, 0, maxn - 1, 1); 90 } 91 92 void opI(int L, int R) { 93 if (L) setSign(false, 0, L - 1, 0, maxn - 1, 1); 94 if (R < maxn) setSign(false, R + 1, maxn - 1, 0, maxn - 1, 1); 95 } 96 97 void opD(int L, int R) { 98 setSign(false, L, R, 0, maxn - 1, 1); 99 } 100 101 void opC(int L, int R) { 102 reverse(L, R, 0, maxn - 1, 1); 103 if (L) setSign(false, 0, L - 1, 0, maxn - 1, 1); 104 if (R < maxn) setSign(false, R + 1, maxn - 1, 0, maxn - 1, 1); 105 } 106 107 void opS(int L, int R) { 108 reverse(L, R, 0, maxn - 1, 1); 109 } 110 111 void getSt(int l, int r, int rt) { 112 if (l == r) { 113 status[l] = sign[rt]; 114 115 return ; 116 } 117 int m = (l + r) >> 1; 118 119 down(rt); 120 getSt(lson); 121 getSt(rson); 122 } 123 124 void getStatus() { 125 getSt(0, maxn - 1, 1); 126 } 127 } segT; 128 129 void convert1(char *buf, int &l, int &r) { 130 bool left, right; 131 132 left = (*buf == '('); 133 buf++; 134 l = r = 0; 135 while (*buf != ',') { 136 l = l * 10 + *buf - '0'; 137 buf++; 138 } 139 buf++; 140 while (*buf != ']' && *buf != ')') { 141 r = r * 10 + *buf - '0'; 142 buf++; 143 } 144 right = (*buf == ')'); 145 146 l = (l << 1) + left; 147 r = (r << 1) - right; 148 } 149 150 void convert2(int l, int r, char *buf) { 151 if (l & 1) { 152 if (r & 1) { 153 sprintf(buf, "(%d,%d)", l >> 1, (r + 1) >> 1); 154 } else { 155 sprintf(buf, "(%d,%d]", l >> 1, r >> 1); 156 } 157 } else { 158 if (r & 1) { 159 sprintf(buf, "[%d,%d)", l >> 1, (r + 1) >> 1); 160 } else { 161 sprintf(buf, "[%d,%d]", l >> 1, r >> 1); 162 } 163 } 164 } 165 166 int main() { 167 int l, r; 168 char op[3], buf[50]; 169 170 freopen("in", "r", stdin); 171 segT.init(); 172 while (~scanf("%s", op)) { 173 scanf("%s", buf); 174 convert1(buf, l, r); 175 // printf("l %d r %d\n", l, r); 176 if (op[0] == 'U') { 177 segT.opU(l, r); 178 } else if (op[0] == 'D') { 179 segT.opD(l, r); 180 } else if (op[0] == 'S') { 181 segT.opS(l, r); 182 } else if (op[0] == 'C') { 183 segT.opC(l, r); 184 } else { 185 segT.opI(l, r); 186 } 187 188 // segT.getStatus(); 189 // for (int i = 0; i < maxn; i++) { 190 // if (status[i]) printf("%d ", i); 191 // } 192 // puts("~~~"); 193 } 194 segT.getStatus(); 195 196 int i = 0, start, end; 197 bool pr = false; 198 199 while (i < maxn) { 200 while (i < maxn && !status[i]) i++; 201 if (i >= maxn) break; 202 start = i; 203 while (i < maxn && status[i]) i++; 204 end = i - 1; 205 convert2(start, end, buf); 206 if (pr) putchar(' '); 207 pr = true; 208 printf("%s", buf); 209 } 210 // for (int i = 0; i < maxn; i++) { 211 // if (status[i]) printf("%d ", i); 212 // } 213 // puts("~~~"); 214 if (!pr) puts("empty set"); 215 else puts(""); 216 217 return 0; 218 }
——written by Lyon