hdu 3397 Sequence operation
Sequence operation
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4393 Accepted Submission(s): 1272
Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Sample Input
1
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
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
2
6
5
Output
For each output operation , output the result.
hdu3911的变形,线段树的合并+延迟标记。
题意:
给你5总操作
x l,r
x==0 将区间[l,r]全部置为0
x==1 将区间[l,r]全部置为1
x==2 将区间[l,r]0的置换为1, 1的置换为0
~~~~~~~~~~~(华丽的分割线)
x==3 输出区间[l,r] 1的个数
x==4 输出区间[l,r] 最长的连续的 1 的个数
思路:hdu3911的变形,建议先做3911试试手。
变量color为延迟标记
当color为 ZERO 代表该区间全部都是0 ,
那么其区间的左端点 右端点的值为0,而且统计1的三个变量的值都为0: one_max , one_lmax, one_rmax;
当color为 ONE 代表该区间全部都是1,同理可知。
当color为 HH 代码该区间的值是置反的。则统计1的三个变量,和统计0的三个变量进行交换。不理解,建议动手画画图。
在向下更新的时候,HH的情况也需要特别的注意。
如果该区间color的值原来为ZERO,那么又遇到了HH,那么变成ONE就可以了。
如果该区间color的值原来是ONE, 那么又遇到了HH,就变成ZERO.
如果该区间color的值原来是HH , 那么就要变成0,
如果该区间color的值原来是0, 那么变成HH。
写了好长的代码, 方法比较笨,时间花销就多了一些。写过最长的代码了,363行。
我想,在比赛中出现这样的题,那简直就是坑爹。
其中为了更容易检查错误,采取了一些对齐。和变量的命名修改,和hdu3911有些区别,
在做hdu3911吃了亏.....
代码:
#include<stdio.h> #define HH 1 #define ZERO 2 #define ONE 3 struct st { int l,r; int lnum,rnum; int one_lmax,one_rmax,one_max; int zer_lmax,zer_rmax,zer_max; int color; int sum; }f[100002*4]; int date[100002]; int max(int x,int y) { if(x>y) return x; else return y; } int min(int x,int y) { if(x<y) return x; else return y; } int Max(int x,int y,int z) { return max(max(x,y),z); } void up(struct st *fa,struct st *lll,struct st *rrr) { fa->lnum=lll->lnum; fa->rnum=rrr->rnum; fa->sum=lll->sum+rrr->sum; if(lll->rnum==0&&rrr->lnum==0) { fa->zer_lmax=(lll->zer_lmax==(lll->r-lll->l+1))? lll->zer_lmax+rrr->zer_lmax:lll->zer_lmax; fa->zer_rmax=(rrr->zer_rmax==(rrr->r-rrr->l+1))? rrr->zer_rmax+lll->zer_rmax:rrr->zer_rmax; fa->zer_max =Max(max(fa->zer_lmax,fa->zer_rmax),max(lll->zer_max,rrr->zer_max),lll->zer_rmax+rrr->zer_lmax); } else { fa->zer_lmax=lll->zer_lmax; fa->zer_rmax=rrr->zer_rmax; fa->zer_max =max(lll->zer_max,rrr->zer_max); } if(lll->rnum==1&&rrr->lnum==1) { fa->one_lmax=(lll->one_lmax==(lll->r-lll->l+1))? lll->one_lmax+rrr->one_lmax:lll->one_lmax; fa->one_rmax=(rrr->one_rmax==(rrr->r-rrr->l+1))? rrr->one_rmax+lll->one_rmax:rrr->one_rmax; fa->one_max =Max(max(fa->one_lmax,fa->one_rmax),max(lll->one_max,rrr->one_max),lll->one_rmax+rrr->one_lmax); } else { fa->one_lmax=lll->one_lmax; fa->one_rmax=rrr->one_rmax; fa->one_max =max(lll->one_max,rrr->one_max); } } void down(int n) { int k; if(f[n].color==ONE) { f[n*2].color=f[n].color; f[n*2].lnum =1; f[n*2].rnum =1; f[n*2].one_lmax=f[n*2].r-f[n*2].l+1; f[n*2].one_rmax=f[n*2].r-f[n*2].l+1; f[n*2].one_max =f[n*2].r-f[n*2].l+1; f[n*2].zer_lmax=0; f[n*2].zer_rmax=0; f[n*2].zer_max =0; f[n*2].sum=f[n*2].r-f[n*2].l+1; f[n*2+1].color=f[n].color; f[n*2+1].lnum =1; f[n*2+1].rnum =1; f[n*2+1].one_lmax=f[n*2+1].r-f[n*2+1].l+1; f[n*2+1].one_rmax=f[n*2+1].r-f[n*2+1].l+1; f[n*2+1].one_max =f[n*2+1].r-f[n*2+1].l+1; f[n*2+1].zer_lmax=0; f[n*2+1].zer_rmax=0; f[n*2+1].zer_max =0; f[n*2+1].sum=f[n*2+1].r-f[n*2+1].l+1; f[n].color=0; } else if(f[n].color==ZERO) { f[n*2].color=f[n].color; f[n*2].lnum=0; f[n*2].rnum=0; f[n*2].one_lmax=0; f[n*2].one_max =0; f[n*2].one_rmax=0; f[n*2].zer_lmax=f[n*2].r-f[n*2].l+1; f[n*2].zer_rmax=f[n*2].r-f[n*2].l+1; f[n*2].zer_max =f[n*2].r-f[n*2].l+1; f[n*2].sum=0; f[n*2+1].color=f[n].color; f[n*2+1].lnum=0; f[n*2+1].rnum=0; f[n*2+1].one_lmax=0; f[n*2+1].one_rmax=0; f[n*2+1].one_max =0; f[n*2+1].zer_lmax=f[n*2+1].r-f[n*2+1].l+1; f[n*2+1].zer_rmax=f[n*2+1].r-f[n*2+1].l+1; f[n*2+1].zer_max =f[n*2+1].r-f[n*2+1].l+1; f[n*2+1].sum=0; f[n].color=0; } else if(f[n].color==HH) { if(f[n*2].color==ONE) f[n*2].color=ZERO; else if(f[n*2].color==ZERO) f[n*2].color=ONE; else if(f[n*2].color==0) f[n*2].color=HH; else if(f[n*2].color==HH) f[n*2].color=0; if(f[n*2].lnum==0) f[n*2].lnum=1; else f[n*2].lnum=0; if(f[n*2].rnum==0) f[n*2].rnum=1; else f[n*2].rnum=0; if(f[n*2+1].color==ONE) f[n*2+1].color=ZERO; else if(f[n*2+1].color==ZERO) f[n*2+1].color=ONE; else if(f[n*2+1].color==0) f[n*2+1].color=HH; else if(f[n*2+1].color==HH) f[n*2+1].color=0; if(f[n*2+1].lnum==0) f[n*2+1].lnum=1; else f[n*2+1].lnum=0; if(f[n*2+1].rnum==0) f[n*2+1].rnum=1; else f[n*2+1].rnum=0; k=f[n*2].one_lmax; f[n*2].one_lmax=f[n*2].zer_lmax; f[n*2].zer_lmax=k; k=f[n*2].one_max; f[n*2].one_max=f[n*2].zer_max; f[n*2].zer_max=k; k=f[n*2].one_rmax; f[n*2].one_rmax=f[n*2].zer_rmax; f[n*2].zer_rmax=k; f[n*2].sum=f[n*2].r-f[n*2].l+1-f[n*2].sum; k=f[n*2+1].one_lmax; f[n*2+1].one_lmax=f[n*2+1].zer_lmax; f[n*2+1].zer_lmax=k; k=f[n*2+1].one_max; f[n*2+1].one_max=f[n*2+1].zer_max; f[n*2+1].zer_max=k; k=f[n*2+1].one_rmax; f[n*2+1].one_rmax=f[n*2+1].zer_rmax; f[n*2+1].zer_rmax=k; f[n*2+1].sum=f[n*2+1].r-f[n*2+1].l+1-f[n*2+1].sum; f[n].color=0; } } void build(int l,int r,int n) { int mid=(l+r)/2; f[n].l=l; f[n].r=r; f[n].color=0; if(l==r) { f[n].lnum=date[l]; f[n].rnum=date[l]; if(date[l]==0) { f[n].zer_lmax=1; f[n].zer_rmax=1; f[n].zer_max=1; f[n].one_lmax=0; f[n].one_rmax=0; f[n].one_max=0; f[n].sum=0; } else if(date[l]==1) { f[n].zer_lmax=0; f[n].zer_rmax=0; f[n].zer_max=0; f[n].one_lmax=1; f[n].one_max=1; f[n].one_rmax=1; f[n].sum=1; } return; } build(l,mid,n*2); build(mid+1,r,n*2+1); up(&f[n],&f[n*2],&f[n*2+1]); } void xx(int n,int x) { int k; if(x==0) { f[n].lnum=0; f[n].rnum=0; f[n].color=ZERO; f[n].one_lmax=0; f[n].one_rmax=0; f[n].one_max =0; f[n].zer_lmax=f[n].r-f[n].l+1; f[n].zer_max =f[n].r-f[n].l+1; f[n].zer_rmax=f[n].r-f[n].l+1; f[n].sum=0; } else if(x==1) { f[n].lnum=1; f[n].rnum=1; f[n].color=ONE; f[n].one_lmax=f[n].r-f[n].l+1; f[n].one_rmax=f[n].r-f[n].l+1; f[n].one_max =f[n].r-f[n].l+1; f[n].zer_lmax=0; f[n].zer_rmax=0; f[n].zer_max =0; f[n].sum=f[n].r-f[n].l+1; } else if(x==2) { if(f[n].color==HH) { f[n].color=0; f[n].sum=f[n].r-f[n].l+1-f[n].sum; } else if(f[n].color==ONE) { f[n].color=ZERO; f[n].sum=0; } else if(f[n].color==ZERO) { f[n].color=ONE; f[n].sum=f[n].r-f[n].l+1; } else if(f[n].color==0) { f[n].color=HH; f[n].sum=f[n].r-f[n].l+1-f[n].sum; } if(f[n].lnum==1) f[n].lnum=0; else f[n].lnum=1; if(f[n].rnum==1) f[n].rnum=0; else f[n].rnum=1; k=f[n].one_lmax; f[n].one_lmax=f[n].zer_lmax; f[n].zer_lmax=k; k=f[n].one_max; f[n].one_max=f[n].zer_max; f[n].zer_max=k; k=f[n].one_rmax; f[n].one_rmax=f[n].zer_rmax; f[n].zer_rmax=k; } } void update(int l,int r,int n,int x) { int mid=(f[n].l+f[n].r)/2; if(f[n].l==l&&f[n].r==r) { xx(n,x); return ; } if(f[n].color!=0) down(n); if(mid>=r) update(l,r,n*2,x); else if(mid<l) update(l,r,n*2+1,x); else { update(l,mid,n*2,x); update(mid+1,r,n*2+1,x); } up(&f[n],&f[n*2],&f[n*2+1]); } int query(int l,int r,int n,int x) { int mid=(f[n].l+f[n].r)/2; int a=0,b=0,ans=0; if(f[n].l==l&&f[n].r==r) { if(x==4) return f[n].one_max; else if(x==3) return f[n].sum; } if(f[n].color!=0) down(n); if(mid>=r) return query(l,r,n*2,x); else if(mid<l) return query(l,r,n*2+1,x); a=query(l,mid,n*2,x); b=query(mid+1,r,n*2+1,x); if(x==3) ans=a+b; else if(f[n*2].rnum==1&&f[n*2+1].lnum==1) ans=Max(a,b,min(mid-l+1,f[n*2].one_rmax)+min(r-mid,f[n*2+1].one_lmax)); else ans=max(a,b); return ans; } int main() { int i,k,n,m,t,l,r,x; while(scanf("%d",&t)>0) { while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&date[i]); build(1,n,1); while(m--) { scanf("%d%d%d",&x,&l,&r); l++,r++; if(x==0||x==1||x==2) { update(l,r,1,x); } else if(x==3||x==4) { k=query(l,r,1,x); printf("%d\n",k); } } } } return 0; }