Description
lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 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 对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?
Input
输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目 第二行包括n个数,表示序列的初始状态 接下来m行,每行3个数,op, a, b,(0 < = op < = 4,0 < = a < = b)
Output
对于每一个询问操作,输出一行,包括1个数,表示其对应的答案
Sample Input
10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
Sample Output
5
2
6
5
调试了半天 变量名打错了。。。
维护区间连续的数 类似于维护最大子段和 一下需要10个名字较长的变量把我整乱了。。。
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100000+50;
int n,m,a[N];
struct point{int ls,rs,lazy,inv,cnt,sum,lsum,rsum,sum0,lsum0,rsum0;}t[4*N];
inline void print(point i)
{printf(" %d %d %d %d %d %d %d %d %d\n\n",i.ls,i.rs,i.cnt,i.sum,i.lsum,i.rsum,i.sum0,i.lsum0,i.rsum0);
//printf(" %d %d %d %d %d %d\n\n",i.ls,i.rs,i.cnt,i.sum,i.lsum,i.rsum);
}
inline void pushup(int i)
{t[i].cnt=t[2*i].cnt+t[2*i+1].cnt;
t[i].lsum=t[2*i].lsum;
if(t[2*i].lsum==(t[2*i].rs-t[2*i].ls+1)) t[i].lsum+=t[2*i+1].lsum;
t[i].rsum=t[2*i+1].rsum;
if(t[2*i+1].rsum==(t[2*i+1].rs-t[2*i+1].ls+1)) t[i].rsum+=t[2*i].rsum;
t[i].sum=max(t[2*i].rsum+t[2*i+1].lsum
,max(max(t[i].lsum,t[i].rsum)
,max(t[2*i].sum,t[2*i+1].sum)));
t[i].lsum0=t[2*i].lsum0;
if(t[2*i].lsum0==t[2*i].rs-t[2*i].ls+1) t[i].lsum0+=t[2*i+1].lsum0;
t[i].rsum0=t[2*i+1].rsum0;
if(t[2*i+1].rsum0==t[2*i+1].rs-t[2*i+1].ls+1) t[i].rsum0+=t[2*i].rsum0;
t[i].sum0=max(t[2*i].rsum0+t[2*i+1].lsum0
,max(max(t[i].lsum0,t[i].rsum0)
,max(t[2*i].sum0,t[2*i+1].sum0)));
}
inline void pass(int i,int x)
{
t[i].lazy=x; t[i].inv=0;
t[i].cnt=t[i].sum=x*(t[i].rs-t[i].ls+1); t[i].sum0=(1-x)*(t[i].rs-t[i].ls+1);
if(x==0) {t[i].lsum=t[i].rsum=0;
t[i].lsum0=t[i].rsum0=t[i].rs-t[i].ls+1;
}
else if(x==1) {t[i].lsum0=t[i].rsum0=0;
t[i].lsum=t[i].rsum=t[i].rs-t[i].ls+1;
}
}
inline void fan(int i)
{ if(t[i].lazy!=-1) {pass(i,t[i].lazy^1); return;}
t[i].inv^=1;
t[i].cnt=t[i].rs-t[i].ls+1-t[i].cnt;
swap(t[i].lsum,t[i].lsum0);
swap(t[i].rsum,t[i].rsum0);
swap(t[i].sum,t[i].sum0);
}
inline void pushdown(int i)
{if(t[i].lazy!=-1)
{pass(2*i,t[i].lazy);
pass(2*i+1,t[i].lazy);
t[i].lazy=-1;
}
if(t[i].inv==1)
{ t[i].inv=0;
fan(2*i); fan(2*i+1);
}
}
void build(int i,int l,int r)
{t[i].ls=l; t[i].rs=r; t[i].lazy=-1;
if(l==r) {t[i].cnt=t[i].sum=t[i].lsum=t[i].rsum=a[l];
t[i].sum0=t[i].lsum0=t[i].rsum0=1-a[l];
return ;
}
int mid=t[i].ls+t[i].rs>>1;
build(i<<1,l,mid); build(2*i+1,mid+1,r);
pushup(i);
}
void change(int i,int l,int r,int x)
{if(l<=t[i].ls && t[i].rs<=r) {pass(i,x); return;}
pushdown(i); int mid=t[i].ls+t[i].rs>>1;
if(l<=mid) change(2*i,l,r,x);
if(mid<r) change(2*i+1,l,r,x);
pushup(i);
}
void rev(int i,int l,int r)
{if(l<=t[i].ls && t[i].rs<=r) {fan(i); return;}
pushdown(i); int mid=t[i].ls+t[i].rs>>1;
if(l<=mid) rev(2*i,l,r);
if(mid<r) rev(2*i+1,l,r);
pushup(i);
}
int ask(int i,int l,int r)
{if(l<=t[i].ls && t[i].rs<=r) {return t[i].cnt;}
pushdown(i); int mid=t[i].ls+t[i].rs>>1; //print(i);
if(r<=mid) return ask(2*i,l,r);
else if(mid<l)return ask(2*i+1,l,r);
else return ask(2*i,l,r)+ask(2*i+1,l,r);
}
point hehe(int i,int l,int r)
{if(l<=t[i].ls && t[i].rs<=r) return t[i];
pushdown(i); int mid=t[i].ls+t[i].rs>>1;
if(r<=mid) return hehe(2*i,l,r);
else if(mid<l)return hehe(2*i+1,l,r);
else {point r1=hehe(2*i,l,r),r2=hehe(2*i+1,l,r),re;
re.cnt=r1.cnt+r2.cnt; re.ls=r1.ls; re.rs=r2.rs;
re.lsum=r1.lsum;
if(r1.lsum==r1.rs-r1.ls+1) re.lsum+=r2.lsum;
re.rsum=r2.rsum;
if(r2.rsum==r2.rs-r2.ls+1) re.rsum+=r1.rsum;
re.sum=max(r1.rsum+r2.lsum,max(max(re.lsum,re.rsum),max(r1.sum,r2.sum)));
return re;
}
}
void shuchu(int i)
{if(t[i].ls==t[i].rs) {print(t[i]); return;}
pushdown(i); print(t[i]);
shuchu(2*i); shuchu(2*i+1);
}
void que(int i)
{if(t[i].ls==t[i].rs) {printf("%d ",t[i].cnt);return;}
pushdown(i);
que(2*i); que(2*i+1);
}
inline int read()
{ int k=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9')k=k*10+ch-'0',ch=getchar();
return k*f;
}
int main()
{
scanf("%d%d",&n,&m); int op,x,y;
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n); // shuchu(1);
//print(t[1]);
while(m--)
{op=read(); x=read(); y=read(); x++,y++;
if(op==0)
{ change(1,x,y,0); //shuchu(1); printf("\n\n\n");
}
else if(op==1)
{ change(1,x,y,1); //shuchu(1); printf("\n\n\n");
}
else if(op==2)
{ rev(1,x,y); //shuchu(1); printf("\n\n\n");
}
else if(op==3)
{ printf("%d\n",ask(1,x,y));// shuchu(1); printf("\n\n\n");
}
else if(op==4)
{ //que(1); printf("\n\n\n");
point ans=hehe(1,x,y);
printf("%d\n",ans.sum);// shuchu(1); printf("\n\n\n");
}
}
return 0;
}