hdu Sequence operation
#include<stdio.h> #define MAXN 100000 struct node{ int sum; int lmax1,rmax1,tmax1; int lmax0,rmax0,tmax0; int cnt; int color; }tree[MAXN*4]; int Total,Interval_max; int max(int a,int b) { return a>b?a:b;} void update_info(int l,int r,int mid,int idx) { tree[idx].sum=tree[idx*2].sum+tree[idx*2+1].sum; tree[idx].lmax1=tree[idx*2].lmax1; if(tree[idx*2].lmax1==(mid-l+1)) tree[idx].lmax1+=tree[idx*2+1].lmax1; tree[idx].rmax1=tree[idx*2+1].rmax1; if(tree[idx*2+1].rmax1==(r-mid)) tree[idx].rmax1+=tree[idx*2].rmax1; tree[idx].tmax1=max(tree[idx*2].tmax1,tree[idx*2+1].tmax1); tree[idx].tmax1=max(tree[idx].tmax1,tree[idx*2].rmax1+tree[idx*2+1].lmax1); tree[idx].lmax0=tree[idx*2].lmax0; if(tree[idx*2].lmax0==(mid-l+1)) tree[idx].lmax0+=tree[idx*2+1].lmax0; tree[idx].rmax0=tree[idx*2+1].rmax0; if(tree[idx*2+1].rmax0==(r-mid)) tree[idx].rmax0+=tree[idx*2].rmax0; tree[idx].tmax0=max(tree[idx*2].tmax0,tree[idx*2+1].tmax0); tree[idx].tmax0=max(tree[idx].tmax0,tree[idx*2].rmax0+tree[idx*2+1].lmax0); } void build(int l,int r,int idx) { tree[idx].color=0; if(l==r) { scanf("%idx",&tree[idx].tmax1); tree[idx].lmax1=tree[idx].rmax1=tree[idx].tmax1; tree[idx].cnt=tree[idx].tmax1; tree[idx].sum=tree[idx].tmax1; tree[idx].lmax0=tree[idx].rmax0=tree[idx].tmax0=1-tree[idx].tmax1; return ; } int m; tree[idx].cnt=-1; m=(l+r)/2; build(l,m,idx*2); build(m+1,r,idx*2+1); update_info(l,r,m,idx); } void push_down(int l,int r,int m,int idx) { if(tree[idx].cnt>=0) { tree[idx].cnt^=tree[idx].color; tree[idx*2].cnt=tree[idx*2+1].cnt=tree[idx].cnt; tree[idx*2].color=0;tree[idx*2+1].color=0; tree[idx*2].sum=tree[idx*2].lmax1=tree[idx*2].rmax1=tree[idx*2].tmax1=tree[idx].cnt*(m-l+1); tree[idx*2].lmax0=tree[idx*2].rmax0=tree[idx*2].tmax0=(1-tree[idx].cnt)*(m-l+1); tree[idx*2+1].sum=tree[idx*2+1].lmax1=tree[idx*2+1].rmax1=tree[idx*2+1].tmax1=tree[idx].cnt*(r-m); tree[idx*2+1].lmax0=tree[idx*2+1].rmax0=tree[idx*2+1].tmax0=(1-tree[idx].cnt)*(r-m); tree[idx].color=0; tree[idx].cnt=-1; return ; } if(tree[idx].color==1) { int t; tree[idx*2].sum=m-l+1-tree[idx*2].sum; t=tree[idx*2].rmax1;tree[idx*2].rmax1=tree[idx*2].rmax0;tree[idx*2].rmax0=t; t=tree[idx*2].lmax1;tree[idx*2].lmax1=tree[idx*2].lmax0;tree[idx*2].lmax0=t; t=tree[idx*2].tmax1;tree[idx*2].tmax1=tree[idx*2].tmax0;tree[idx*2].tmax0=t; tree[idx*2+1].sum=r-m-tree[idx*2+1].sum; t=tree[idx*2+1].rmax1;tree[idx*2+1].rmax1=tree[idx*2+1].rmax0;tree[idx*2+1].rmax0=t; t=tree[idx*2+1].lmax1;tree[idx*2+1].lmax1=tree[idx*2+1].lmax0;tree[idx*2+1].lmax0=t; t=tree[idx*2+1].tmax1;tree[idx*2+1].tmax1=tree[idx*2+1].tmax0;tree[idx*2+1].tmax0=t; tree[idx*2].color^=1; tree[idx*2+1].color^=1; tree[idx].color=0; } } void update(int a,int b,int cnt,int l,int r,int idx) { if(a<=l&&r<=b) { tree[idx].cnt=cnt; tree[idx].color=0; tree[idx].sum=tree[idx].lmax1=tree[idx].rmax1=tree[idx].tmax1=cnt*(r-l+1); tree[idx].rmax0=tree[idx].lmax0=tree[idx].tmax0=(1-cnt)*(r-l+1); return; } int mid=(l+r)/2; push_down(l,r,mid,idx); if(a<=mid) update(a,b,cnt,l,mid,idx*2); if(b>mid) update(a,b,cnt,mid+1,r,idx*2+1); update_info(l,r,mid,idx); } void update_xor(int a,int b,int l,int r,int idx) { if(a<=l&&r<=b) { int t; tree[idx].color^=1; tree[idx].sum=r-l+1-tree[idx].sum; t=tree[idx].rmax1;tree[idx].rmax1=tree[idx].rmax0;tree[idx].rmax0=t; t=tree[idx].lmax1;tree[idx].lmax1=tree[idx].lmax0;tree[idx].lmax0=t; t=tree[idx].tmax1;tree[idx].tmax1=tree[idx].tmax0;tree[idx].tmax0=t; return; } int m=(l+r)/2; push_down(l,r,m,idx); if(a<=m) update_xor(a,b,l,m,idx*2); if(b>m) update_xor(a,b,m+1,r,idx*2+1); update_info(l,r,m,idx); } void Query_sum(int a,int b,int l,int r,int idx) { if(a<=l&&r<=b) { Total+=tree[idx].sum; return; } int mid=(l+r)/2; push_down(l,r,mid,idx); if(a<=mid) Query_sum(a,b,l,mid,idx*2); if(b>mid) Query_sum(a,b,mid+1,r,idx*2+1); update_info(l,r,mid,idx); } void Query_Interval(int a,int b,int l,int r,int idx) { if(a<=l&&r<=b) { if(Interval_max<tree[idx].tmax1) Interval_max=tree[idx].tmax1; return; } int mid=(l+r)/2; push_down(l,r,mid,idx); if(a<=mid&&mid<b) { int s=0; if((mid-a+1)>tree[idx*2].rmax1) s+=tree[idx*2].rmax1; else s+=mid-a+1; if((b-mid)>tree[idx*2+1].lmax1) s+=tree[idx*2+1].lmax1; else s+=b-mid; if(s>Interval_max) Interval_max=s; } if(a<=mid&&Interval_max<tree[idx*2].tmax1) Query_Interval(a,b,l,mid,idx*2); if(b>mid&&Interval_max<tree[idx*2+1].tmax1) Query_Interval(a,b,mid+1,r,idx*2+1); update_info(l,r,mid,idx); } int main() { int n,m,t; int a,b,op; scanf("%idx",&t); while(t--) { scanf("%d %d",&n,&m); n--; build(0,n,1); while(m--) { scanf("%d %d %d",&op,&a,&b); if(op==0||op==1) { update(a,b,op,0,n,1); } if(op==2) { update_xor(a,b,0,n,1); } if(op==3) { Total=0; Query_sum(a,b,0,n,1); printf("%d\n",Total); } if(op==4) { Interval_max=0; Query_Interval(a,b,0,n,1); printf("%d\n",Interval_max); } } } return 0; }