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]序列操作

BZOJ_1858_[Scoi2010]序列操作_线段树

bzoj1858[Scoi2010]序列操作

AC日记——[Scoi2010]序列操作 bzoj 1858

bzoj 1858: [Scoi2010]序列操作

BZOJ 1858 SCOI2010 序列操作 线段树