1. 程式人生 > >解題:SCOI 2010 序列操作

解題:SCOI 2010 序列操作

圖片 view 模板 技術 long spa lap ++ int

題面

線段樹......模板題(霧?

然而兩種標記會互相影響,必須保證每次只放一個(不然就不知道怎麽放了),具體的影響就是:

翻轉標記會使得覆蓋標記一起翻轉,下放的時候就是各種swap

覆蓋標記會抹掉翻轉標記,下放的時候好像挺正常的

然後就是碼碼碼+細節

技術分享圖片
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 const int N=100005;
  6 struct a{int ll,rr,vv;};
  7 int val[4
*N],last[4*N][2],lst[4*N][2],rst[4*N][2]; 8 int num[N],laz1[4*N],laz2[4*N]; 9 int n,m,t1,t2,t3; 10 void pushup(int nde,int l,int r) 11 { 12 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 13 val[nde]=val[ls]+val[rs]; 14 //value 15 lst[nde][1]=(last[ls][1]==mid-l+1)?last[ls][1]+lst[rs][1]:lst[ls][1
]; 16 rst[nde][1]=(last[rs][1]==r-mid)?last[rs][1]+rst[ls][1]:rst[rs][1]; 17 last[nde][1]=max(rst[ls][1]+lst[rs][1],max(last[ls][1],last[rs][1])); 18 //longest continuing one 19 lst[nde][0]=(last[ls][0]==mid-l+1)?last[ls][0]+lst[rs][0]:lst[ls][0]; 20 rst[nde][0]=(last[rs][0]==r-mid)?last[rs][0
]+rst[ls][0]:rst[rs][0]; 21 last[nde][0]=max(rst[ls][0]+lst[rs][0],max(last[ls][0],last[rs][0])); 22 //longest continuing zero 23 } 24 void create(int nde,int l,int r) 25 { 26 if(l==r) 27 { 28 last[nde][0]=lst[nde][0]=rst[nde][0]=(num[l]^1); 29 val[nde]=last[nde][1]=lst[nde][1]=rst[nde][1]=num[l]; 30 } 31 else 32 { 33 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 34 create(ls,l,mid),create(rs,mid+1,r); 35 pushup(nde,l,r); 36 } 37 } 38 void release(int nde,int l,int r) 39 { 40 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 41 if(laz2[nde]) 42 { 43 if(~laz1[ls]) laz1[ls]^=1; else laz2[ls]^=1; 44 if(~laz1[rs]) laz1[rs]^=1; else laz2[rs]^=1; 45 val[ls]=(mid-l+1)-val[ls],val[rs]=(r-mid)-val[rs]; 46 //reversing 47 swap(last[ls][0],last[ls][1]),swap(last[rs][0],last[rs][1]); 48 swap(lst[ls][0],lst[ls][1]),swap(lst[rs][0],lst[rs][1]); 49 swap(rst[ls][0],rst[ls][1]),swap(rst[rs][0],rst[rs][1]); 50 //a lot of swaps...... 51 laz2[nde]=0; 52 //refresh 53 } 54 //release the lazy tag of intervals reversing 55 else if(~laz1[nde]) 56 { 57 laz1[ls]=laz1[nde],laz1[rs]=laz1[nde],laz2[ls]=0,laz2[rs]=0; 58 //to the left/right son 59 val[ls]=last[ls][1]=lst[ls][1]=rst[ls][1]=(mid-l+1)*laz1[nde]; 60 val[rs]=last[rs][1]=lst[rs][1]=rst[rs][1]=(r-mid)*laz1[nde]; 61 //longest continuing one 62 last[ls][0]=lst[ls][0]=rst[ls][0]=(mid-l+1)*(laz1[nde]^1); 63 last[rs][0]=lst[rs][0]=rst[rs][0]=(r-mid)*(laz1[nde]^1); 64 //longest continuing zero 65 laz1[nde]=-1; 66 //refresh 67 } 68 //release the lazy tag of intervals covering 69 } 70 void Change(int nde,int l,int r,int nl,int nr,int task) 71 { 72 if(l>nr||r<nl) 73 return ; 74 else if(l>=nl&&r<=nr) 75 { 76 last[nde][0]=lst[nde][0]=rst[nde][0]=(task^1)*(r-l+1); 77 val[nde]=last[nde][1]=lst[nde][1]=rst[nde][1]=task*(r-l+1); 78 laz1[nde]=task,laz2[nde]=0; 79 } 80 else 81 { 82 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r); 83 Change(ls,l,mid,nl,nr,task),Change(rs,mid+1,r,nl,nr,task); 84 pushup(nde,l,r); 85 } 86 } 87 void Reverse(int nde,int l,int r,int nl,int nr) 88 { 89 if(l>nr||r<nl) 90 return ; 91 else if(l>=nl&&r<=nr) 92 { 93 val[nde]=(r-l+1)-val[nde],swap(last[nde][0],last[nde][1]); 94 swap(lst[nde][0],lst[nde][1]),swap(rst[nde][0],rst[nde][1]); 95 if(~laz1[nde]) laz1[nde]^=1; else laz2[nde]^=1; 96 } 97 else 98 { 99 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r); 100 Reverse(ls,l,mid,nl,nr),Reverse(rs,mid+1,r,nl,nr); pushup(nde,l,r); 101 } 102 } 103 int Vquery(int nde,int l,int r,int nl,int nr) 104 { 105 if(l>nr||r<nl) 106 return 0; 107 else if(l>=nl&&r<=nr) 108 return val[nde]; 109 else 110 { 111 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r); 112 return Vquery(ls,l,mid,nl,nr)+Vquery(rs,mid+1,r,nl,nr); 113 } 114 } 115 a Lquery(int nde,int l,int r,int nl,int nr) 116 { 117 if(l>=nl&&r<=nr) 118 return (a){lst[nde][1],rst[nde][1],last[nde][1]}; 119 else 120 { 121 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r); 122 if(nr<=mid) return Lquery(ls,l,mid,nl,nr); 123 if(nl>mid) return Lquery(rs,mid+1,r,nl,nr); 124 a Q1=Lquery(ls,l,mid,nl,nr),Q2=Lquery(rs,mid+1,r,nl,nr),ret; 125 ret.vv=max(max(Q1.vv,Q2.vv),Q1.rr+Q2.ll); 126 ret.ll=(Q1.vv==(mid-l+1))?Q1.vv+Q2.ll:Q1.ll; 127 ret.rr=(Q2.vv==(r-mid))?Q2.vv+Q1.rr:Q2.rr; 128 return ret; 129 } 130 } 131 int main () 132 { 133 scanf("%d%d",&n,&m); 134 for(int i=1;i<=n;i++) 135 scanf("%d",&num[i]); 136 create(1,1,n); 137 memset(laz1,-1,sizeof laz1); 138 for(int i=1;i<=m;i++) 139 { 140 scanf("%d%d%d",&t1,&t2,&t3),t2++,t3++; 141 if(!t1) Change(1,1,n,t2,t3,0); 142 else if(t1==1) Change(1,1,n,t2,t3,1); 143 else if(t1==2) Reverse(1,1,n,t2,t3); 144 else if(t1==3) printf("%d\n",Vquery(1,1,n,t2,t3)); 145 else printf("%d\n",Lquery(1,1,n,t2,t3).vv); 146 } 147 return 0; 148 }
View Code

解題:SCOI 2010 序列操作