|
1 | 1 | #include <algorithm>
|
2 |
| -#include <bitset> |
3 | 2 | #include <cstdio>
|
4 |
| -#include <cstring> |
5 |
| -#include <iostream> |
6 |
| -#include <queue> |
7 |
| -#define MAXN 50016 |
8 |
| -#define LL long long |
9 |
| -using namespace std; |
10 |
| -int n; |
11 |
| -char a[MAXN], b[MAXN]; |
12 |
| -int sum[MAXN]; |
13 |
| -int minn, maxx; |
14 |
| -bitset<MAXN> S[MAXN], ans, L, map1, map0; |
15 |
| -void init() |
| 3 | + |
| 4 | +const int maxn = 2e5 + 10; |
| 5 | + |
| 6 | +struct PersistentSegTree |
16 | 7 | {
|
17 |
| - map1 = map0 = ans = L = bitset<MAXN>(); |
18 |
| - for (int i = 0; i <= maxx - minn; i++) S[i] = bitset<MAXN>(); |
19 |
| - minn = maxx = 0; |
20 |
| - for (int i = 1; i <= n; i++) sum[i] = 0; |
21 |
| -} |
| 8 | + struct node |
| 9 | + { |
| 10 | + int ls, rs; |
| 11 | + long long sum, tag; |
| 12 | + } A[maxn << 5]; |
| 13 | + int a[maxn], cnt; |
| 14 | + inline void clear() { cnt = 0; } |
| 15 | + inline int newnode() { return ++cnt; } |
| 16 | + inline int newnode(int old) |
| 17 | + { |
| 18 | + if (!old) return newnode(); |
| 19 | + A[++cnt] = A[old]; |
| 20 | + return cnt; |
| 21 | + } |
| 22 | + int seg_add(int l, int r, int p, int ll, int rr, int k) |
| 23 | + { |
| 24 | + int now = newnode(p); |
| 25 | + A[now].sum += 1ll * k * (std::min(rr,r) - std::max(l,ll) + 1); |
| 26 | + if (l >= ll && r <= rr) return A[now].tag += k, now; |
| 27 | + int mid = (l + r) >> 1; |
| 28 | + if (ll <= mid) A[now].ls = seg_add(l, mid, A[now].ls, ll, rr, k); |
| 29 | + if (rr > mid) A[now].rs = seg_add(mid + 1,r,A[now].rs, ll, rr, k); |
| 30 | + return now; |
| 31 | + } |
| 32 | + long long ask(int l,int r,int p, int ll, int rr, long long tagsum) |
| 33 | + { |
| 34 | + if(!p) return 0; |
| 35 | + if (l >= ll && r <= rr) return A[p].sum + tagsum * (r - l + 1); |
| 36 | + int mid = (l + r) >> 1; |
| 37 | + long long ret = 0; |
| 38 | + tagsum += A[p].tag; |
| 39 | + if (ll <= mid) ret += ask(l,mid,A[p].ls, ll, rr, tagsum); |
| 40 | + if (rr > mid) ret += ask(mid + 1,r,A[p].rs, ll, rr, tagsum); |
| 41 | + return ret; |
| 42 | + } |
| 43 | +}; |
| 44 | +PersistentSegTree T; |
| 45 | +int n, m, root[maxn]; |
22 | 46 | int main()
|
23 | 47 | {
|
24 |
| - // freopen("input.txt","r",stdin); |
25 |
| - int t; |
26 |
| - scanf("%d", &t); |
27 |
| - while (t--) |
| 48 | + scanf("%d%d", &n, &m); |
| 49 | + for (int i = 1; i <= n; ++i) scanf("%d", T.a + i); |
| 50 | + for (int i = 1; i <= n; ++i) root[0] = T.seg_add(1,n,root[0], i, i, T.a[i]); |
| 51 | + for (int t = 1; t <= m; ++t) |
28 | 52 | {
|
29 |
| - init(); |
30 |
| - |
31 |
| - ans = ~ans; |
32 |
| - scanf("%d", &n); |
33 |
| - scanf("%s", a + 1); |
34 |
| - scanf("%s", b + 1); |
35 |
| - |
36 |
| - for (int i = 1; i <= n; i++) |
37 |
| - { |
38 |
| - sum[i] = sum[i - 1] + ((a[i] - '0') ? 1 : -1); |
39 |
| - minn = min(minn, sum[i]); |
40 |
| - maxx = max(maxx, sum[i]); |
41 |
| - } |
42 |
| - |
43 |
| - bitset<MAXN>* T = S - minn; |
44 |
| - |
45 |
| - T[0][n] = 1; |
46 |
| - map1 = ~map1; // all 1 ,map1 all 0 |
47 |
| - |
48 |
| - for (int i = 1, presum = 0; i <= n; i++) |
49 |
| - { |
50 |
| - map0[i] = 1; |
51 |
| - map1[i] = 0; |
52 |
| - |
53 |
| - if (a[i] == '0') |
54 |
| - L ^= T[--presum]; |
55 |
| - else |
56 |
| - L ^= T[presum++]; |
57 |
| - T[presum][n - i] = 1; |
58 |
| - int hi = L[n]; |
59 |
| - if (hi) |
60 |
| - ans &= (b[i] == '1' ? (L >> (n - i)) | map1 : ~((L >> (n - i)) | map1)); |
61 |
| - else |
62 |
| - ans &= (b[i] == '1' ? (L >> (n - i)) & map0 : ~((L >> (n - i)) & map0)); |
63 |
| - } |
64 |
| - for (int i = 1; i <= n; i++) printf("%d", ans[i] ? 1 : 0); |
65 |
| - putchar('\n'); |
| 53 | + int opt, x, y, k; |
| 54 | + scanf("%d%d%d", &opt, &x, &y); |
| 55 | + if (opt == 1) |
| 56 | + scanf("%d", &k), root[t] = T.seg_add(1,n,root[t - 1], x, y, k); |
| 57 | + else |
| 58 | + root[t] = root[t - 1], printf("%lld\n", T.ask(1,n,root[t], x, y, 0)); |
66 | 59 | }
|
67 | 60 | return 0;
|
68 | 61 | }
|
0 commit comments