http://acm.hdu.edu.cn/showproblem.php?pid=3397
空间要开大点不然就RE。更新比较复杂,在取反时要注意先向下更新。
如这样的数据:
1
10 10
0 0 0 1 1 0 1 0 1 1
2 0 9
2 0 9
4 0 2
1 0 9
2 0 8
4 0 2
1
#include <iostream>
2
#include <cstdio>
3
#include <cstring>
4
#define
lson l,mid,i<<1
5
#define
rson mid+1,r,i<<1|1
6
using
namespace
std;
7
const
int
Ni =
100100
;
8
int
n;
9
struct
node {
10
int
sum1,sum0;
11
int
mx1,lm1,rm1;
12
int
mx0,lm0,rm0;
13
int
lnum,rnum;
14
}tree[Ni<<
3
];
15
int
color[Ni<<
3
];
16
inline
void
changes(
int
i)
17
{
18
swap(tree[i].mx1,tree[i].mx0);
19
swap(tree[i].sum1,tree[i].sum0);
20
swap(tree[i].lm1,tree[i].lm0);
21
swap(tree[i].rm1,tree[i].rm0);
22
tree[i].lnum=!
tree[i].lnum;
23
tree[i].rnum=!
tree[i].rnum;
24
}
25
inline
void
pushup(
int
l,
int
r,
int
i)
26
{
27
tree[i].mx1=max(tree[i<<
1
].mx1,tree[i<<
1
|
1
].mx1);
///
111111
28
if
(tree[i<<
1
].rnum==
1
&&tree[i<<
1
|
1
].lnum==
1
)
29
{
30
tree[i].mx1=max(tree[i].mx1,tree[i<<
1
].rm1+tree[i<<
1
|
1
].lm1);
31
}
32
int
mid=(l+r)>>
1
;
33
if
(tree[i<<
1
].mx1==mid-l+
1
&&tree[i<<
1
].rnum==
1
&&tree[i<<
1
|
1
].lnum==
1
)
34
tree[i].lm1=tree[i<<
1
].mx1+tree[i<<
1
|
1
].lm1;
35
else
36
tree[i].lm1=tree[i<<
1
].lm1;
37
38
if
(tree[i<<
1
|
1
].mx1==r-mid&&tree[i<<
1
].rnum==
1
&&tree[i<<
1
|
1
].lnum==
1
)
39
tree[i].rm1=tree[i<<
1
|
1
].mx1+tree[i<<
1
].rm1;
40
else
41
tree[i].rm1=tree[i<<
1
|
1
].rm1;
42
tree[i].lnum=tree[i<<
1
].lnum;
43
tree[i].rnum=tree[i<<
1
|
1
].rnum;
44
tree[i].sum1=tree[i<<
1
].sum1+tree[i<<
1
|
1
].sum1;
45
46
tree[i].mx0=max(tree[i<<
1
].mx0,tree[i<<
1
|
1
].mx0);
///
000000
47
if
(tree[i<<
1
].rnum==
0
&&tree[i<<
1
|
1
].lnum==
0
)
48
{
49
tree[i].mx0=max(tree[i].mx0,tree[i<<
1
].rm0+tree[i<<
1
|
1
].lm0);
50
}
51
mid=(l+r)>>
1
;
52
if
(tree[i<<
1
].mx0==mid-l+
1
&&tree[i<<
1
].rnum==
0
&&tree[i<<
1
|
1
].lnum==
0
)
53
tree[i].lm0=tree[i<<
1
].mx0+tree[i<<
1
|
1
].lm0;
54
else
55
tree[i].lm0=tree[i<<
1
].lm0;
56
57
if
(tree[i<<
1
|
1
].mx0==r-mid&&tree[i<<
1
].rnum==
0
&&tree[i<<
1
|
1
].lnum==
0
)
58
tree[i].rm0=tree[i<<
1
|
1
].mx0+tree[i<<
1
].rm0;
59
else
60
tree[i].rm0=tree[i<<
1
|
1
].rm0;
61
tree[i].lnum=tree[i<<
1
].lnum;
62
tree[i].rnum=tree[i<<
1
|
1
].rnum;
63
tree[i].sum0=tree[i<<
1
].sum0+tree[i<<
1
|
1
].sum0;
64
}
65
inline
void
pushdown(
int
l,
int
r,
int
i)
66
{
67
if
(color[i]==-
8
)
return
;
68
if
(color[i]==
1
)
69
{
70
color[i<<
1
]=color[i<<
1
|
1
]=
1
;
71
color[i]=-
8
;
72
int
mid=(l+r)>>
1
;
73
tree[i<<
1
].mx1=tree[i<<
1
].sum1=mid-l+
1
;
74
tree[i<<
1
].lm1=tree[i<<
1
].rm1=mid-l+
1
;
75
tree[i<<
1
].mx0=tree[i<<
1
].sum0=
0
;
76
tree[i<<
1
].lm0=tree[i<<
1
].rm0=
0
;
77
tree[i<<
1
].lnum=tree[i<<
1
].rnum=
1
;
78
79
tree[i<<
1
|
1
].mx1=tree[i<<
1
|
1
].sum1=r-
mid;
80
tree[i<<
1
|
1
].lm1=tree[i<<
1
|
1
].rm1=r-
mid;
81
tree[i<<
1
|
1
].mx0=tree[i<<
1
|
1
].sum0=
0
;
82
tree[i<<
1
|
1
].lm0=tree[i<<
1
|
1
].rm0=
0
;
83
tree[i<<
1
|
1
].lnum=tree[i<<
1
|
1
].rnum=
1
;
84
}
else
if
(color[i]==
0
)
85
{
86
color[i<<
1
]=color[i<<
1
|
1
]=
0
;
87
color[i]=-
8
;
88
int
mid=(l+r)>>
1
;
89
tree[i<<
1
].mx1=tree[i<<
1
].sum1=
0
;
90
tree[i<<
1
].lm1=tree[i<<
1
].rm1=
0
;
91
tree[i<<
1
].mx0=tree[i<<
1
].sum0=mid-l+
1
;
92
tree[i<<
1
].lm0=tree[i<<
1
].rm0=mid-l+
1
;
93
tree[i<<
1
].lnum=tree[i<<
1
].rnum=
0
;
94
95
tree[i<<
1
|
1
].mx1=tree[i<<
1
|
1
].sum1=
0
;
96
tree[i<<
1
|
1
].lm1=tree[i<<
1
|
1
].rm1=
0
;
97
tree[i<<
1
|
1
].mx0=tree[i<<
1
|
1
].sum0=r-
mid;
98
tree[i<<
1
|
1
].lm0=tree[i<<
1
|
1
].rm0=r-
mid;
99
tree[i<<
1
|
1
].lnum=tree[i<<
1
|
1
].rnum=
0
;
100
}
else
if
(color[i]==
2
)
101
{
102
if
(l<
r){
103
int
mid=(l+r)>>
1
;
104
pushdown(l,mid,i<<
1
);
105
pushdown(mid+
1
,r,i<<
1
|
1
);
106
}
107
color[i<<
1
]=color[i<<
1
|
1
]=
2
;
108
color[i]=-
8
;
109
changes(i<<
1
);
110
changes(i<<
1
|
1
);
111
}
112
}
113
void
build(
int
l=
1
,
int
r=n,
int
i=
1
)
114
{
115
color[i]=-
8
;
116
if
(l==
r)
117
{
118
int
num;
119
scanf(
"
%d
"
,&
num);
120
tree[i].lnum=tree[i].rnum=
num;
121
122
tree[i].sum1=tree[i].mx1=
num;
123
tree[i].lm1=tree[i].rm1=
num;
124
125
tree[i].sum0=tree[i].mx0=!
num;
126
tree[i].lm0=tree[i].rm0=!
num;
127
return
;
128
}
129
int
mid=(l+r)>>
1
;
130
build(lson);
131
build(rson);
132
pushup(l,r,i);
133
}
134
int
query(
int
ql,
int
qr,
int
flg,
int
l=
1
,
int
r=n,
int
i=
1
)
135
{
136
int
ans=
0
;
137
if
(flg==
4
)
138
{
139
int
lsum=
0
,rsum=
0
;
140
if
(ql<=l&&r<=qr)
return
tree[i].mx1;
141
int
mid=(l+r)>>
1
;
142
pushdown(l,r,i);
143
if
(tree[i<<
1
].rnum==
1
&&tree[i<<
1
|
1
].lnum==
1
)
144
{
145
int
lsum,rsum;
146
lsum=min(mid-ql+
1
,tree[i<<
1
].rm1);
147
rsum=min(qr-mid,tree[i<<
1
|
1
].lm1);
148
ans=lsum+
rsum;
149
}
150
if
(ql<=mid) lsum=
query(ql,qr,flg,lson);
151
if
(qr>mid) rsum=
query(ql,qr,flg,rson);
152
ans=
max(ans,lsum);
153
ans=
max(ans,rsum);
154
}
155
else
156
{
157
if
(ql<=l&&r<=qr)
return
tree[i].sum1;
158
int
mid=(l+r)>>
1
;
159
pushdown(l,r,i);
160
if
(ql<=mid) ans+=
query(ql,qr,flg,lson);
161
if
(qr>mid) ans+=
query(ql,qr,flg,rson);
162
}
163
return
ans;
164
}
165
void
update(
int
ql,
int
qr,
int
num,
int
l=
1
,
int
r=n,
int
i=
1
)
166
{
167
if
(ql<=l&&r<=
qr)
168
{
169
if
(num==
1
)
170
{
171
tree[i].mx1=tree[i].sum1=(r-l+
1
);
172
tree[i].lm1=tree[i].rm1=(r-l+
1
);
173
174
tree[i].mx0=tree[i].sum0=
0
;
175
tree[i].lm0=tree[i].rm0=
0
;
176
177
tree[i].lnum=tree[i].rnum=
num;
178
color[i]=
num;
179
}
180
else
if
(num==
0
)
181
{
182
tree[i].mx1=tree[i].sum1=
0
;
183
tree[i].lm1=tree[i].rm1=
0
;
184
185
tree[i].mx0=tree[i].sum0=(r-l+
1
);
186
tree[i].lm0=tree[i].rm0=(r-l+
1
);
187
188
tree[i].lnum=tree[i].rnum=
num;
189
color[i]=
num;
190
}
191
else
if
(num==
2
)
192
{
193
if
(color[i]==
2
)
194
{
195
color[i]=-
8
;
196
}
197
else
198
{
199
if
(l<
r)
200
pushdown(l,r,i);
201
color[i]=
2
;
202
}
203
changes(i);
204
}
205
return
;
206
}
207
pushdown(l,r,i);
208
int
mid=(l+r)>>
1
;
209
if
(ql<=
mid) update(ql,qr,num,lson);
210
if
(qr>
mid) update(ql,qr,num,rson);
211
pushup(l,r,i);
212
}
213
int
main()
214
{
215
int
m,i,t,l,r,f;
216
cin>>
t;
217
while
(t--
)
218
{
219
scanf(
"
%d%d
"
,&n,&
m);
220
build();
221
for
(i=
0
;i<m;i++
)
222
{
223
scanf(
"
%d%d%d
"
,&f,&l,&
r);
224
l++;r++
;
225
if
(f<
3
)
226
{
227
update(l,r,f);
228
}
229
else
230
{
231
int
ans=
query(l,r,f);
232
printf(
"
%d\n
"
,ans);
233
}
234
}
235
}
236
return
0
;
237
}

