题意:
给定一个N<=100000个数的01序列,要你支持共Q<=100000个五种操作
0 a b 把[a, b]区间内的所有数全变成0
1 a b 把[a, b]区间内的所有数全变成1
2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0
3 a b 询问[a, b]区间内总共有多少个1
4 a b 询问[a, b]区间内最多有多少个连续的1
做法:
我只会用很傻逼的方法(虽然在八中oj上跑的最快)
线段树里保存很多很多值:
左边开始最多有多少个0 多少个1
右边开始最多有多少个0 多少个1
区间内最大连续有多少个0 多少个1
区间总共有多少个0 多少个1
区间是否被0或者1 覆盖
区间是否被取反
如果没有取反的操作 那么就很简单
有了取反的操作:
假设取反前已经被0或者1覆盖 那么把这个值取反
如果没有被0或者1覆盖 那么将 区间取反标记 取反
如果该区间被覆盖了 无论之前有没有被取反 取反标记都是无用的
这样就可以解决这个问题了。。
ps:这个题调了我2个小时。。结果是因为懒得写Rch 直接复制Lch 有几个地方还是Lch 没改成Rch....好2的错误
1
#include <cstdio>
2
3
#define Lch(t) (t<<1)
4
#define Rch(t) ((t<<1)+1)
5
#define max(a,b) ((a)>(b)?(a):(b))
6
struct Tnode
7

{
8
int lm[2],rm[2],d[2],s[2],m[2],last;
9
bool inv;
10
} T[400005];
11
int A[100005],N,M;
12
inline void swap(int &u,int &v)
13

{
14
int t=u;u=v;v=t;
15
}
16
inline void Downdraw(int t,int L,int R,int c)
17

{
18
T[Lch(t)].lm[c]=T[Lch(t)].rm[c]=T[Lch(t)].m[c]=T[Lch(t)].s[c]=L;
19
T[Lch(t)].lm[c^1]=T[Lch(t)].rm[c^1]=T[Lch(t)].m[c^1]=T[Lch(t)].m[c^1]=T[Lch(t)].s[c^1]=0;
20
T[Lch(t)].d[c]=1,T[Lch(t)].d[c^1]=0;
21
T[Rch(t)].lm[c]=T[Rch(t)].rm[c]=T[Rch(t)].m[c]=T[Rch(t)].s[c]=R;
22
T[Rch(t)].lm[c^1]=T[Rch(t)].rm[c^1]=T[Rch(t)].m[c^1]=T[Rch(t)].m[c^1]=T[Rch(t)].s[c^1]=0;
23
T[Rch(t)].d[c]=1,T[Rch(t)].d[c^1]=0;
24
T[Lch(t)].inv=T[Rch(t)].inv=0;
25
T[t].d[c]=0;
26
}
27
inline void Downinve(int t,int L,int R)
28

{
29
swap(T[Lch(t)].lm[0],T[Lch(t)].lm[1]);
30
swap(T[Lch(t)].rm[0],T[Lch(t)].rm[1]);
31
swap(T[Lch(t)].m[0],T[Lch(t)].m[1]);
32
swap(T[Lch(t)].s[0],T[Lch(t)].s[1]);
33
swap(T[Lch(t)].d[0],T[Lch(t)].d[1]);
34
if (!T[Lch(t)].d[0]&&!T[Lch(t)].d[1]) T[Lch(t)].inv^=1;
35
swap(T[Rch(t)].lm[0],T[Rch(t)].lm[1]);
36
swap(T[Rch(t)].rm[0],T[Rch(t)].rm[1]);
37
swap(T[Rch(t)].m[0],T[Rch(t)].m[1]);
38
swap(T[Rch(t)].s[0],T[Rch(t)].s[1]);
39
swap(T[Rch(t)].d[0],T[Rch(t)].d[1]);
40
if (!T[Rch(t)].d[0]&&!T[Rch(t)].d[1]) T[Rch(t)].inv^=1;
41
T[t].inv=0;
42
}
43
inline void Down(int t,int L,int R)
44

{
45
int c=-1;
46
if (T[t].d[0]>0) c=0;
47
if (T[t].d[1]>0) c=1;
48
if (c>=0) Downdraw(t,L,R,c);
49
else
50
if (T[t].inv) Downinve(t,L,R);
51
}
52
inline void Update(Tnode &t,Tnode &l,Tnode &r,int L,int R)
53

{
54
for (int i=0;i<2;++i)
55
{
56
t.lm[i]=l.lm[i],t.rm[i]=r.rm[i];
57
if (l.lm[i]==L) t.lm[i]=L+r.lm[i];
58
if (r.rm[i]==R) t.rm[i]=l.rm[i]+R;
59
t.s[i]=l.s[i]+r.s[i];
60
t.m[i]=max(l.m[i],r.m[i]);
61
t.m[i]=max(t.m[i],l.rm[i]+r.lm[i]);
62
}
63
}
64
inline void Build(int t,int l,int r)
65

{
66
if (l==r)
67
{
68
T[t].lm[A[l]]=T[t].rm[A[l]]=T[t].m[A[l]]=T[t].s[A[l]]=1;
69
return;
70
}
71
int mid=(l+r)>>1,L=mid-l+1,R=r-mid;
72
Down(t,L,R);
73
Build(Lch(t),l,mid);
74
Build(Rch(t),mid+1,r);
75
Update(T[t],T[Lch(t)],T[Rch(t)],L,R);
76
}
77
inline void Draw(int t,int l,int r,int ll,int rr,int c)
78

{
79
if (ll==l&&rr==r)
80
{
81
T[t].lm[c]=T[t].rm[c]=T[t].m[c]=T[t].m[c]=T[t].s[c]=r-l+1;
82
T[t].lm[c^1]=T[t].rm[c^1]=T[t].m[c^1]=T[t].m[c^1]=T[t].s[c^1]=0;
83
T[t].d[c]=1,T[t].d[c^1]=0;
84
T[t].inv=0;
85
return;
86
}
87
int mid=(l+r)>>1,L=mid-l+1,R=r-mid;
88
Down(t,L,R);
89
if (rr<=mid) Draw(Lch(t),l,mid,ll,rr,c);
90
else
91
if (ll>mid) Draw(Rch(t),mid+1,r,ll,rr,c);
92
else
93
{
94
Draw(Lch(t),l,mid,ll,mid,c);
95
Draw(Rch(t),mid+1,r,mid+1,rr,c);
96
}
97
Update(T[t],T[Lch(t)],T[Rch(t)],L,R);
98
}
99
inline void Inverse(int t,int l,int r,int ll,int rr)
100

{
101
if (ll==l&&rr==r)
102
{
103
swap(T[t].lm[0],T[t].lm[1]);
104
swap(T[t].rm[0],T[t].rm[1]);
105
swap(T[t].m[0],T[t].m[1]);
106
swap(T[t].s[0],T[t].s[1]);
107
swap(T[t].d[0],T[t].d[1]);
108
if (!T[t].d[0]&&!T[t].d[1]) T[t].inv^=1;
109
return;
110
}
111
int mid=(l+r)>>1,L=mid-l+1,R=r-mid;
112
Down(t,L,R);
113
if (rr<=mid) Inverse(Lch(t),l,mid,ll,rr);
114
else
115
if (ll>mid) Inverse(Rch(t),mid+1,r,ll,rr);
116
else
117
{
118
Inverse(Lch(t),l,mid,ll,mid);
119
Inverse(Rch(t),mid+1,r,mid+1,rr);
120
}
121
Update(T[t],T[Lch(t)],T[Rch(t)],L,R);
122
}
123
inline Tnode Query(int t,int l,int r,int ll,int rr)
124

{
125
if (ll==l&&rr==r) return T[t];
126
int mid=(l+r)>>1,L=mid-l+1,R=r-mid;
127
Down(t,L,R);
128
if (rr<=mid) return Query(Lch(t),l,mid,ll,rr);
129
if (ll>mid) return Query(Rch(t),mid+1,r,ll,rr);
130
Tnode left=Query(Lch(t),l,mid,ll,mid);
131
Tnode right=Query(Rch(t),mid+1,r,mid+1,rr);
132
Tnode ret;Update(ret,left,right,L,R);
133
return ret;
134
}
135
int main()
136

{
137
int a,b,c;
138
scanf("%d%d",&N,&M);
139
for (int i=1;i<=N;++i)
140
scanf("%d",&A[i]);
141
Build(1,1,N);
142
for (;M--;)
143
{
144
scanf("%d%d%d",&c,&a,&b),++a,++b;
145
if (c<2) Draw(1,1,N,a,b,c);
146
else
147
if (c==2) Inverse(1,1,N,a,b);
148
else
149
if (c==3) printf("%d\n",Query(1,1,N,a,b).s[1]);
150
else printf("%d\n",Query(1,1,N,a,b).m[1]);
151
}
152
return 0;
153
}
154