bzoj 1858: [Scoi2010]序列操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1858: [Scoi2010]序列操作相关的知识,希望对你有一定的参考价值。
2016-06-21
一看就是线段树,就是标记相互冲突,处理好,其余都是平常的。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<queue> 6 #include<cstdlib> 7 #include<map> 8 #define ll long long 9 #define M 500009 10 using namespace std; 11 ll read() 12 { 13 char ch=getchar(); 14 ll x=0,f=1; 15 for(;ch<‘0‘||ch>‘9‘;ch=getchar()) 16 if(ch==‘-‘) 17 f=-1; 18 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) 19 x=x*10+ch-‘0‘; 20 return x*f; 21 } 22 struct data 23 { 24 int l[2],r[2],le[2],su,yi,laz; 25 }shu[M]; 26 int n,m,a[M]; 27 void geng(int x,int l1,int l2) 28 { 29 int l=x*2,r=x*2+1; 30 shu[x].su=shu[l].su+shu[r].su; 31 for(int i=0;i<2;i++) 32 { 33 shu[x].le[i]=max(max(shu[l].le[i],shu[r].le[i]),shu[l].r[i]+shu[r].l[i]); 34 shu[x].l[i]=shu[l].l[i]; 35 if(shu[x].l[i]==l1) 36 shu[x].l[i]+=shu[r].l[i]; 37 shu[x].r[i]=shu[r].r[i]; 38 if(shu[x].r[i]==l2) 39 shu[x].r[i]+=shu[l].r[i]; 40 } 41 } 42 void build(int x,int l,int r) 43 { 44 if(l==r) 45 { 46 shu[x].l[a[l]]=shu[x].le[a[l]]=shu[x].r[a[l]]=1; 47 shu[x].su=a[l]; 48 return; 49 } 50 int mid=(l+r)>>1; 51 build(x*2,l,mid); 52 build(x*2+1,mid+1,r); 53 geng(x,mid-l+1,r-mid); 54 } 55 void gg(int x,int k,int len) 56 { 57 shu[x].su=len*k; 58 shu[x].l[k]=shu[x].r[k]=shu[x].le[k]=len; 59 shu[x].l[k^1]=shu[x].r[k^1]=shu[x].le[k^1]=shu[x].yi=0; 60 shu[x].laz=k+1; 61 } 62 void ggg(int x,int l1) 63 { 64 shu[x].su=l1-shu[x].su; 65 swap(shu[x].l[0],shu[x].l[1]); 66 swap(shu[x].r[0],shu[x].r[1]); 67 swap(shu[x].le[0],shu[x].le[1]); 68 if(!shu[x].laz) 69 shu[x].yi^=1; 70 else 71 shu[x].laz=((shu[x].laz-1)^1)+1; 72 } 73 void updata(int x,int l1,int l2) 74 { 75 int l=x*2,r=x*2+1; 76 if(shu[x].yi) 77 { 78 shu[x].yi=0; 79 ggg(l,l1); 80 ggg(r,l2); 81 } 82 if(shu[x].laz) 83 { 84 int k=shu[x].laz-1; 85 shu[x].laz=0; 86 gg(l,k,l1); 87 gg(r,k,l2); 88 } 89 } 90 void gai(int x,int l,int r,int L,int R,int k) 91 { 92 if(l>=L&&r<=R) 93 { 94 gg(x,k,r-l+1); 95 return; 96 } 97 int mid=(l+r)>>1; 98 updata(x,mid-l+1,r-mid); 99 if(L<=mid) 100 gai(x*2,l,mid,L,R,k); 101 if(R>mid) 102 gai(x*2+1,mid+1,r,L,R,k); 103 geng(x,mid-l+1,r-mid); 104 } 105 void fan(int x,int l,int r,int L,int R) 106 { 107 if(l>=L&&r<=R) 108 { 109 ggg(x,r-l+1); 110 return; 111 } 112 int mid=(l+r)>>1; 113 updata(x,mid-l+1,r-mid); 114 if(L<=mid) 115 fan(x*2,l,mid,L,R); 116 if(R>mid) 117 fan(x*2+1,mid+1,r,L,R); 118 geng(x,mid-l+1,r-mid); 119 } 120 int query(int x,int l,int r,int L,int R) 121 { 122 if(l>=L&&r<=R) 123 return shu[x].su; 124 125 int mid=(l+r)>>1,ans=0; 126 updata(x,mid-l+1,r-mid); 127 if(L<=mid) 128 ans+=query(x*2,l,mid,L,R); 129 if(R>mid) 130 ans+=query(x*2+1,mid+1,r,L,R); 131 return ans; 132 } 133 int query1(int x,int l,int r,int L,int R) 134 { 135 if(l>=L&&r<=R) 136 return shu[x].le[1]; 137 int mid=(l+r)>>1,ans=0,l1=0,r1=0; 138 updata(x,mid-l+1,r-mid); 139 if(L<=mid) 140 { 141 ans=max(ans,query1(x*2,l,mid,L,R)); 142 if(R>mid) 143 l1=min(shu[x*2].r[1],mid-max(l,L)+1); 144 } 145 if(R>mid) 146 { 147 ans=max(ans,query1(x*2+1,mid+1,r,L,R)); 148 if(L<=mid) 149 r1=min(shu[x*2+1].l[1],min(r,R)-mid); 150 } 151 ans=max(ans,l1+r1); 152 return ans; 153 } 154 int main() 155 { 156 n=read(); 157 m=read(); 158 for(int i=1;i<=n;i++) 159 a[i]=read(); 160 build(1,1,n); 161 for(int i=1;i<=m;i++) 162 { 163 int k=read(),A=read()+1,B=read()+1; 164 if(k<2) 165 gai(1,1,n,A,B,k); 166 if(k==2) 167 fan(1,1,n,A,B); 168 if(k==3) 169 printf("%d\n",query(1,1,n,A,B)); 170 if(k==4) 171 printf("%d\n",query1(1,1,n,A,B)); 172 } 173 return 0; 174 }
以上是关于bzoj 1858: [Scoi2010]序列操作的主要内容,如果未能解决你的问题,请参考以下文章
bzoj千题计划177:bzoj1858: [Scoi2010]序列操作