解:发现这苟东西是个3千万位的二进制数......毒瘤吧。
拆位考虑,如果一个地方本来是1然后+1,就会把它和它前面连续的一段1变成0,并把第一个0变成1。
如果本来是0然后-1了,就会把它和它前面连续的一段0变成1,并把第一个1变成0。
然后发现这两个操作都可以用线段树。于是得到了一个60分算法。
然后压位,线段树每一位表示30个二进制位,可以发现之前的性质没变:如果一个地方加了后超过了(1<<30)-1,就把前面的一段1变成0,第一个0变成1。减法同理。
注意加法爆了就对(1<<30)-1取&,减法爆了就加上(1<<30),这里千万不能-1,因为是从前面借的。
有个地方坑死我了......看这里。
应该长这样...
1 #include <bits/stdc++.h> 2 3 inline void read(int &x) { 4 x = 0; 5 char c = getchar(); 6 bool f = 0; 7 while(c < '0' || c > '9') { 8 if(c == '-') f = 1; 9 c = getchar(); 10 } 11 while(c >= '0' && c <= '9') { 12 x = x * 10 + c - 48; 13 c = getchar(); 14 } 15 if(f) x = (~x) + 1; 16 return; 17 } 18 19 const int N = 4000010, FULL = (1 << 30) - 1; 20 21 inline void out(int x) { 22 for(int i = 0; i <= 29; i++) printf("%d", (x >> i) & 1); 23 return; 24 } 25 26 int n, tag[N], val[N], sta[N], lm; 27 /// tag is_same now_state 28 29 inline void pushup(int o) { 30 if(val[o << 1] == val[o << 1 | 1] && val[o << 1] != -1) { 31 val[o] = val[o << 1]; 32 } 33 else val[o] = -1; 34 return; 35 } 36 37 inline void pushdown(int o) { 38 if(tag[o] != -1) { 39 tag[o << 1] = tag[o << 1 | 1] = tag[o]; 40 val[o << 1] = val[o << 1 | 1] = tag[o]; 41 sta[o << 1] = sta[o << 1 | 1] = (tag[o] ? FULL : 0); 42 tag[o] = -1; 43 } 44 return; 45 } 46 47 void changeAdd(int l, int r, int o) { 48 if(l == r) { 49 for(int i = 0; i < 30; i++) { 50 if(((sta[o] >> i) & 1) == 0) { 51 sta[o] |= (1 << i); 52 break; 53 } 54 else { 55 sta[o] &= ~(1 << i); 56 } 57 } 58 if(sta[o] == FULL) val[o] = 1; 59 else if(sta[o] == 0) val[o] = 0; 60 else val[o] = -1; 61 return; 62 } 63 int mid = (l + r) >> 1; 64 pushdown(o); 65 if(val[o << 1] != 1) { 66 changeAdd(l, mid, o << 1); 67 } 68 else { 69 changeAdd(mid + 1, r, o << 1 | 1); 70 sta[o << 1] = val[o << 1] = tag[o << 1] = 0; 71 } 72 pushup(o); 73 return; 74 } 75 76 void changeDel(int l, int r, int o) { 77 if(l == r) { 78 for(int i = 0; i < 30; i++) { 79 if((sta[o] >> i) & 1) { 80 sta[o] &= ~(1 << i); 81 break; 82 } 83 else { 84 sta[o] |= (1 << i); 85 } 86 } 87 if(sta[o] == FULL) val[o] = 1; 88 else if(sta[o] == 0) val[o] = 0; 89 else val[o] = -1; 90 return; 91 } 92 int mid = (l + r) >> 1; 93 pushdown(o); 94 if(val[o << 1] != 0) { 95 changeDel(l, mid, o << 1); 96 } 97 else { 98 changeDel(mid + 1, r, o << 1 | 1); 99 val[o << 1] = tag[o << 1] = 1; 100 sta[o << 1] = FULL; 101 } 102 pushup(o); 103 return; 104 } 105 106 int add(int p, int v, int l, int r, int o) { 107 if(l == r) { 108 sta[o] += v; 109 int t = 0; 110 if(sta[o] > FULL) { 111 sta[o] &= FULL; 112 t = 1; 113 } 114 if(sta[o] == FULL) val[o] = 1; 115 else if(sta[o] == 0) val[o] = 0; 116 else val[o] = -1; 117 return t; 118 } 119 int mid = (l + r) >> 1; 120 pushdown(o); 121 int t; 122 if(p <= mid) { 123 t = add(p, v, l, mid, o << 1); 124 pushup(o); 125 if(t && val[o << 1 | 1] != 1) { 126 changeAdd(mid + 1, r, o << 1 | 1); 127 pushup(o); 128 return 0; 129 } 130 else if(t) { 131 tag[o << 1 | 1] = val[o << 1 | 1] = sta[o << 1 | 1] = 0; 132 pushup(o); 133 return 1; 134 } 135 else return 0; 136 } 137 else { 138 t = add(p, v, mid + 1, r, o << 1 | 1); 139 pushup(o); 140 return t; 141 } 142 return 0; 143 } 144 145 int del(int p, int v, int l, int r, int o) { 146 if(l == r) { 147 sta[o] -= v; 148 int t = 0; 149 if(sta[o] < 0) { 150 sta[o] += FULL + 1; 151 t = 1; 152 } 153 if(sta[o] == FULL) val[o] = 1; 154 else if(sta[o] == 0) val[o] = 0; 155 else val[o] = -1; 156 return t; 157 } 158 int mid = (l + r) >> 1; 159 pushdown(o); 160 int t; 161 if(p <= mid) { 162 t = del(p, v, l, mid, o << 1); 163 pushup(o); 164 if(t && val[o << 1 | 1] != 0) { 165 changeDel(mid + 1, r, o << 1 | 1); 166 pushup(o); 167 return 0; 168 } 169 else if(t) { 170 tag[o << 1 | 1] = val[o << 1 | 1] = 1; 171 sta[o << 1 | 1] = FULL; 172 pushup(o); 173 return 1; 174 } 175 else return 0; 176 } 177 else { 178 t = del(p, v, mid + 1, r, o << 1 | 1); 179 pushup(o); 180 return t; 181 } 182 return 0; 183 } 184 185 inline void Add(int p, int x) { /// node p add x 186 if(!x) return; 187 add(p, x, 1, lm, 1); 188 return; 189 } 190 191 inline void Del(int p, int x) { 192 if(!x) return; 193 del(p, x, 1, lm, 1); 194 return; 195 } 196 197 int ask(int p, int l, int r, int o) { 198 if(l == r) { 199 p -= (l - 1) * 30; 200 return (sta[o] >> p) & 1; 201 } 202 int mid = (l + r) >> 1; 203 pushdown(o); 204 if(p <= mid * 30 - 1) return ask(p, l, mid, o << 1); 205 else return ask(p, mid + 1, r, o << 1 | 1); 206 } 207 208 void out(int l, int r, int o) { 209 if(l == r) { 210 return; 211 } 212 int mid = (l + r) >> 1; 213 pushdown(o); 214 out(l, mid, o << 1); 215 out(mid + 1, r, o << 1 | 1); 216 return; 217 } 218 219 int main() { 220 int t1, t2, t3; 221 memset(tag, -1, sizeof(tag)); 222 scanf("%d%d%d%d", &n, &t1, &t2, &t3); 223 lm = std::max(n + 10, 200); 224 for(int i = 1, f, x, y; i <= n; i++) { 225 scanf("%d%d", &f, &x); 226 if(f == 2) { 227 printf("%d ", ask(x, 1, lm, 1)); 228 } 229 else { 230 scanf("%d", &y); 231 int t, fd = 0; 232 if(x < 0) { 233 x = -x; 234 fd = 1; 235 } 236 if(!fd) { /// add 237 t = (x << (y % 30)) & FULL; 238 Add(y / 30 + 1, t); 239 t = x >> (30 - (y % 30)); 240 Add(y / 30 + 2, t); 241 } 242 else { /// dec 243 t = (x << (y % 30)) & FULL; 244 Del(y / 30 + 1, t); 245 t = x >> (30 - (y % 30)); 246 Del(y / 30 + 2, t); 247 } 248 } 249 } 250 return 0; 251 }