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
HINT
对于30%的数据,1<=n, m<=1000 对于100%的数据,1< = n, m < = 100000
题目分析
真是该AFO了 从第一份代码里调出了不下10个严重bug......
线段树维护l[0],l[1],r[0],r[1],all[0],all[1],sum
代表从左端点开始的连续0的个数,左端点开始的连续1的个数,从右端点开始的连续0的个数,右端点开始的连续1的个数
区间最大连续0的个数,区间最大连续1的个数,区间和(区间内1的个数)
然后推一推就好了
写的代码及其恶心QAQ
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
int n,m;
int val[101000];
struct your
{
int x,y;
int cover,add;
int sum;
int l[3],r[3],all[3];
}a[401000];
int cnt;
void add_pushdown(int num)
{
a[num<<1].add=a[num<<1|1].add=a[num].add;
a[num<<1].sum=(a[num<<1].y-a[num<<1].x+1)*a[num].add;
a[num<<1|1].sum=(a[num<<1|1].y-a[num<<1|1].x+1)*a[num].add;
a[num<<1].l[a[num].add]=a[num<<1].r[a[num].add]=a[num<<1].all[a[num].add]=a[num<<1].y-a[num<<1].x+1;
a[num<<1|1].l[a[num].add]=a[num<<1|1].r[a[num].add]=a[num<<1|1].all[a[num].add]=a[num<<1|1].y-a[num<<1|1].x+1;
a[num].add^=1;
a[num<<1].l[a[num].add]=a[num<<1|1].l[a[num].add]=a[num<<1].r[a[num].add]=a[num<<1|1].r[a[num].add]=a[num<<1].all[a[num].add]=a[num<<1|1].all[a[num].add]=0;
a[num].cover=a[num<<1].cover=a[num<<1|1].cover=0;
a[num].add=-1;
}
void cover_pushdown(int num)
{
a[num<<1].sum=(a[num<<1].y-a[num<<1].x+1)-a[num<<1].sum;
a[num<<1|1].sum=(a[num<<1|1].y-a[num<<1|1].x+1)-a[num<<1|1].sum;
swap(a[num<<1].l[0],a[num<<1].l[1]),swap(a[num<<1|1].l[0],a[num<<1|1].l[1]);
swap(a[num<<1].r[0],a[num<<1].r[1]),swap(a[num<<1|1].r[0],a[num<<1|1].r[1]);
swap(a[num<<1].all[0],a[num<<1].all[1]),swap(a[num<<1|1].all[0],a[num<<1|1].all[1]);
if(a[num<<1].add!=-1) a[num<<1].add^=1;
else a[num<<1].cover^=1;
if(a[num<<1|1].add!=-1) a[num<<1|1].add^=1;
else a[num<<1|1].cover^=1;
a[num].cover=0;
}
void push_up(int num)
{
a[num].sum=a[num<<1].sum+a[num<<1|1].sum;
a[num].l[0]=(a[num<<1].l[0]==(a[num<<1].y-a[num<<1].x+1))?a[num<<1|1].l[0]+a[num<<1].l[0]:a[num<<1].l[0];
a[num].l[1]=(a[num<<1].l[1]==(a[num<<1].y-a[num<<1].x+1))?a[num<<1|1].l[1]+a[num<<1].l[1]:a[num<<1].l[1];
a[num].r[0]=(a[num<<1|1].r[0]==(a[num<<1|1].y-a[num<<1|1].x+1))?a[num<<1].r[0]+a[num<<1|1].r[0]:a[num<<1|1].r[0];
a[num].r[1]=(a[num<<1|1].r[1]==(a[num<<1|1].y-a[num<<1|1].x+1))?a[num<<1].r[1]+a[num<<1|1].r[1]:a[num<<1|1].r[1];
a[num].all[0]=max(max(a[num<<1].all[0],a[num<<1|1].all[0]),a[num<<1].r[0]+a[num<<1|1].l[0]);
a[num].all[1]=max(max(a[num<<1].all[1],a[num<<1|1].all[1]),a[num<<1].r[1]+a[num<<1|1].l[1]);
return ;
}
void build(int dx,int dy,int num)
{
cnt++;
a[num].x=dx,a[num].y=dy;
a[num].add=-1;
if(dx==dy)
{
a[num].sum=val[dx];
a[num].l[val[dx]]=a[num].r[val[dx]]=a[num].all[val[dx]]=1;
return ;
}
int mid=(dx+dy)>>1;
build(dx,mid,num<<1),build(mid+1,dy,num<<1|1);
push_up(num);
}
void update(int dx,int dy,int c,int num)
{
if(a[num].x==dx&&a[num].y==dy)
{
a[num].add=c;
a[num].sum=(a[num].y-a[num].x+1)*c;
a[num].l[c]=a[num].r[c]=a[num].all[c]=a[num].y-a[num].x+1;
a[num].l[c^1]=a[num].r[c^1]=a[num].all[c^1]=0;
a[num].cover=0;
return ;
}
if(a[num].add!=-1) add_pushdown(num);
if(a[num].cover) cover_pushdown(num);
int mid=(a[num].x+a[num].y)>>1;
if(dx>mid) update(dx,dy,c,num<<1|1);
else if(dy<=mid) update(dx,dy,c,num<<1);
else update(dx,mid,c,num<<1),update(mid+1,dy,c,num<<1|1);
push_up(num);
}
void cover(int dx,int dy,int num)
{
if(a[num].x==dx&&a[num].y==dy)
{
a[num].sum=(a[num].y-a[num].x+1)-a[num].sum;
swap(a[num].l[0],a[num].l[1]);
swap(a[num].r[0],a[num].r[1]);
swap(a[num].all[0],a[num].all[1]);
if(a[num].add!=-1) a[num].add^=1;
else a[num].cover^=1;
return ;
}
if(a[num].add!=-1) add_pushdown(num);
if(a[num].cover) cover_pushdown(num);
int mid=(a[num].x+a[num].y)>>1;
if(dx>mid) cover(dx,dy,num<<1|1);
else if(dy<=mid) cover(dx,dy,num<<1);
else cover(dx,mid,num<<1),cover(mid+1,dy,num<<1|1);
push_up(num);
}
int ask(int dx,int dy,int num,int color)
{
if(a[num].x==dx&&a[num].y==dy)
return !color?a[num].sum:a[num].all[1];
if(a[num].add!=-1) add_pushdown(num);
if(a[num].cover) cover_pushdown(num);
int mid=(a[num].x+a[num].y)>>1;
if(dx>mid) return ask(dx,dy,num<<1|1,color);
if(dy<=mid) return ask(dx,dy,num<<1,color);
if(!color) return ask(dx,mid,num<<1,color)+ask(mid+1,dy,num<<1|1,color);
else
{
int tmp=max(ask(dx,mid,num<<1,color),ask(mid+1,dy,num<<1|1,color));
int nmp=min(mid-dx+1,a[num<<1].r[1])+min(dy-mid,a[num<<1|1].l[1]);
return max(tmp,nmp);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
build(1,n,1);
for(int i=1;i<=m;i++)
{
int tmp,x,y;
scanf("%d%d%d",&tmp,&x,&y);
x++,y++;
if(tmp==0) update(x,y,0,1);
else if(tmp==1) update(x,y,1,1);
else if(tmp==2) cover(x,y,1);
else if(tmp==3) printf("%d\n",ask(x,y,1,0));
else if(tmp==4) printf("%d\n",ask(x,y,1,1));
}
return 0;
}