LOJ#2302 整数

解:发现这苟东西是个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\n", 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 }
AC代码

 

posted @ 2019-03-16 15:50  huyufeifei  阅读(145)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

ReadEra 阅读书籍

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜