难在异或对询问区间最大连续1长度的影响,每次异或时,把异或标记更新到底(cover标记不为-1),直接更新当前最大连续1区间的长度。
1 # include <stdio.h>
2
3 # define N 100005
4
5 # define ls ((r)<<1)
6 # define rs ((r)<<1|1)
7 # define mid (((x)+(y))>>1)
8
9 int n, m, a[N];
10 int cover[N<<2];
11 int sum[N<<2], lcon[N<<2], rcon[N<<2], tcon[N<<2];
12
13 int Max(int x, int y)
14 {
15 return x > y ? x : y;
16 }
17
18 int Min(int x, int y)
19 {
20 return x < y ? x : y;
21 }
22
23 void update(int r, int x, int y)
24 {
25 sum[r] = sum[ls] + sum[rs];
26 lcon[r] = lcon[ls], rcon[r] = rcon[rs];
27 if (lcon[ls] == mid-x+1) lcon[r] += lcon[rs];
28 if (rcon[rs] == y-mid) rcon[r] += rcon[ls];
29 tcon[r] = Max(rcon[ls]+lcon[rs], Max(tcon[ls], tcon[rs]));
30 }
31
32 void pushdown(int r, int x, int y)
33 {
34 if (cover[r] != -1)
35 {
36 cover[ls] = cover[rs] = cover[r];
37 sum[ls] = (cover[r] ? mid-x+1:0);
38 sum[rs] = (cover[r] ? y-mid:0);
39 lcon[ls] = rcon[ls] = tcon[ls] = sum[ls];
40 lcon[rs] = rcon[rs] = tcon[rs] = sum[rs];
41 cover[r] = -1;
42 }
43 }
44
45 void build(int r, int x, int y)
46 {
47 cover[r] = -1;
48 if (x == y)
49 {
50 cover[r] = sum[r] = a[x];
51 lcon[r] = rcon[r] = tcon[r] = a[x];
52 return ;
53 }
54 build(ls, x, mid);
55 build(rs, mid+1, y);
56 update(r, x, y);
57 }
58
59 void change(int r, int x, int y, int s, int t, int val)
60 {
61 if (s<=x && y<=t)
62 {
63 cover[r] = val;
64 sum[r] = (val ? y-x+1:0);
65 lcon[r] = rcon[r] = tcon[r] = sum[r];
66 return ;
67 }
68 pushdown(r, x, y);
69 if (s <= mid) change(ls, x, mid, s, t, val);
70 if (mid+1<=t) change(rs, mid+1, y, s, t, val);
71 update(r, x, y);
72 }
73
74 void query_sum(int r, int x, int y, int s, int t, int *ans)
75 {
76 if (s<=x && y<=t)
77 {
78 *ans += sum[r];
79 return ;
80 }
81 pushdown(r, x, y);
82 if (s <= mid) query_sum(ls, x, mid, s, t, ans);
83 if (mid+1<=t) query_sum(rs, mid+1, y, s, t, ans);
84 }
85
86 /******************************************************/
87 void procxor(int r, int x, int y, int s, int t)
88 {
89 if (s<=x && y<=t)
90 {
91 if (cover[r] != -1)
92 {
93 cover[r] ^= 1;
94 sum[r] = (cover[r] ? y-x+1:0);
95 lcon[r] = rcon[r] = tcon[r] = sum[r];
96 return ;
97 }
98 }
99 pushdown(r, x, y);
100 if (s <= mid) procxor(ls, x, mid, s, t);
101 if (mid+1 <= t) procxor(rs, mid+1, y, s, t);
102 update(r, x, y);
103 }
104
105 int query_len(int r, int x, int y, int s, int t)
106 {
107 int a, b, c;
108 if (s==x && y==t) return tcon[r];
109 pushdown(r, x, y);
110 if (t <= mid) return query_len(ls, x, mid, s, t);
111 else if (s >= mid+1) return query_len(rs, mid+1, y, s, t);
112 else
113 {
114 a = query_len(ls, x, mid, s, mid);
115 b = query_len(rs, mid+1, y, mid+1, t);
116 c = Min(rcon[ls], mid-s+1)+Min(lcon[rs], t-mid);
117 return Max(a, Max(b, c));
118 }
119 }
120 /******************************************************/
121 void solve(void)
122 {
123 int i, op, s, t, ans;
124 scanf("%d%d", &n, &m);
125 for (i = 1; i <= n; ++i) scanf("%d", &a[i]);
126 build(1, 1, n);
127 for (i = 1; i <= m; ++i)
128 {
129 scanf("%d%d%d", &op, &s, &t), ++s, ++t;
130 switch(op)
131 {
132 case 0: change(1, 1, n, s, t, 0); break;
133 case 1: change(1, 1, n, s, t, 1); break;
134 case 2: procxor(1, 1, n, s, t); break;
135 case 3: ans = 0, query_sum(1, 1, n, s, t, &ans), printf("%d\n", ans); break;
136 case 4: ans = query_len(1, 1, n, s, t), printf("%d\n", ans); break;
137 }
138 }
139 }
140
141 int main()
142 {
143 int T;
144 scanf("%d", &T);
145 while (T--) solve();
146 return 0;
147 }