bzoj1858 [Scoi2010]序列操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1858 [Scoi2010]序列操作相关的知识,希望对你有一定的参考价值。
恶心线段树
既然要翻转我就对0、1分别用一个information结构体存信息,翻转就直接swap
注意标记的优先次序。。。(坑
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=1;ch=getchar();} 30 while(ch>=‘0‘&&ch<=‘9‘)ret*=10,ret+=ch-‘0‘,ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,m; 34 struct information 35 { 36 int Max,maxl,maxr,sum; 37 information(){Max=maxl=maxr=sum=0;} 38 information(int Max,int maxl,int maxr,int sum):Max(Max),maxl(maxl),maxr(maxr),sum(sum){} 39 }; 40 struct segmenttree 41 { 42 int l,r,change; 43 information in[2]; 44 segmenttree(){change=-1;} 45 }t[400010]; 46 int a[100010]; 47 void update(int k) 48 { 49 int p1=k<<1,p2=p1|1,l=t[k].l,r=t[k].r,mid=(l+r)>>1; 50 re(i,0,1) 51 { 52 t[k].in[i].Max= 53 max(t[p1].in[i].maxr+t[p2].in[i].maxl, 54 max(t[p1].in[i].Max, t[p2].in[i].Max)); 55 t[k].in[i].maxl= 56 max(t[p1].in[i].maxl, 57 (t[p1].in[i].maxl==mid-l+1?mid-l+1+t[p2].in[i].maxl:0)); 58 t[k].in[i].maxr= 59 max(t[p2].in[i].maxr, 60 (t[p2].in[i].maxr==r-mid?r-mid+t[p1].in[i].maxr:0)); 61 t[k].in[i].sum=t[p1].in[i].sum+t[p2].in[i].sum; 62 } 63 } 64 void build(int k,int l,int r) 65 { 66 t[k].l=l,t[k].r=r; 67 if(l==r){t[k].in[a[l]]=information(1,1,1,1);return ;} 68 int mid=(l+r)>>1; 69 build(k<<1,l,mid); 70 build(k<<1|1,mid+1,r); 71 update(k); 72 } 73 void down(int k) 74 { 75 int p1=k<<1,p2=k<<1|1; 76 int x=t[k].change,y=x^1,len1=t[p1].r-t[p1].l+1,len2=t[p2].r-t[p2].l+1; 77 if(x!=-1) 78 if(x!=2) 79 { 80 t[p1].change=t[p2].change=x; 81 t[p1].in[x]=information(len1,len1,len1,len1); 82 t[p1].in[y]=information(0,0,0,0); 83 t[p2].in[x]=information(len2,len2,len2,len2); 84 t[p2].in[y]=information(0,0,0,0); 85 t[k].change=-1; 86 } 87 else 88 { 89 t[k].change=-1; 90 swap(t[p1].in[0],t[p1].in[1]); 92 if(t[p1].change!=-1) 93 if(t[p1].change==2)t[p1].change=-1;else t[p1].change^=1; 95 else t[p1].change=2; 97 swap(t[p2].in[0],t[p2].in[1]); 99 if(t[p2].change!=-1) 100 if(t[p2].change==2)t[p2].change=-1;else t[p2].change^=1; 102 else t[p2].change=2; 103 }else ; 105 update(k); 106 } 107 void change(int k,int l,int r,int x) 108 { 109 if(t[k].l>=l&&t[k].r<=r) 110 { 111 t[k].change=x; 112 int y=x^1,len=t[k].r-t[k].l+1; 113 t[k].in[x]=information(len,len,len,len); 114 t[k].in[y]=information(0,0,0,0); 115 return ; 116 } 117 down(k); 118 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 119 if(r<=mid)change(p1,l,r,x); 120 else if(l>mid)change(p2,l,r,x); 121 else change(p1,l,r,x),change(p2,l,r,x); 122 update(k); 123 } 124 void change2(int k,int l,int r) 125 { 126 if(t[k].l>=l&&t[k].r<=r) 127 { 128 swap(t[k].in[0],t[k].in[1]); 129 if(t[k].change!=-1) 130 if(t[k].change==2)t[k].change=-1; 131 else t[k].change^=1; 132 else t[k].change=2; 133 return ; 134 } 135 down(k); 136 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 137 if(r<=mid)change2(p1,l,r); 138 else if(l>mid)change2(p2,l,r); 139 else change2(p1,l,r),change2(p2,l,r); 140 update(k); 141 } 142 int queryl(int k,int l,int r) 143 { 144 if(t[k].l>=l&&t[k].r<=r)return t[k].in[1].maxl; 145 down(k); 146 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 147 if(r<=mid)return queryl(p1,l,r); 148 if(l>mid)return queryl(p2,l,r); 149 int ret=queryl(p1,l,r);if(ret==t[p1].r-t[p1].l+1)ret+=queryl(p2,l,r); 150 return ret; 151 } 152 int queryr(int k,int l,int r) 153 { 154 if(t[k].l>=l&&t[k].r<=r)return t[k].in[1].maxr; 155 down(k); 156 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 157 if(r<=mid)return queryr(p1,l,r); 158 if(l>mid)return queryr(p2,l,r); 159 int ret=queryr(p2,l,r);if(ret==t[p2].r-t[p2].l+1)ret+=queryr(p1,l,r); 160 return ret; 161 } 162 int query2(int k,int l,int r) 163 { 164 if(t[k].l>=l&&t[k].r<=r)return t[k].in[1].Max; 165 down(k); 166 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 167 if(r<=mid)return query2(p1,l,r); 168 if(l>mid)return query2(p2,l,r); 169 return max(max(query2(p1,l,r),query2(p2,l,r)),queryl(p2,l,r)+queryr(p1,l,r)); 170 } 171 int query(int k,int l,int r) 172 { 173 if(t[k].l>=l&&t[k].r<=r)return t[k].in[1].sum; 174 down(k); 175 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 176 if(r<=mid)return query(p1,l,r); 177 if(l>mid)return query(p2,l,r); 178 return query(p1,l,r)+query(p2,l,r); 179 } 188 int CSC() 189 { 190 freopen("in.in","r",stdin); 191 freopen("out.out","w",stdout); 192 inin(n),inin(m); 193 re(i,1,n)inin(a[i]); 194 build(1,1,n); 195 re(i,1,m) 196 { 197 int opt,l,r; 198 inin(opt),inin(l),inin(r);l++,r++; 199 if(opt==0)change(1,l,r,0); 200 if(opt==1)change(1,l,r,1); 201 if(opt==2)change2(1,l,r); 202 if(opt==3)cout<<query(1,l,r)<<"\n"; 203 if(opt==4)cout<<query2(1,l,r)<<"\n"; 206 } 207 return 0; 208 }
以上是关于bzoj1858 [Scoi2010]序列操作的主要内容,如果未能解决你的问题,请参考以下文章