1序列操作(题目链接)
这个题是线段树的基础综合运用题。对于细节要求特别高,需要对每一个标记以及互相之间的关系相当清晰。大体的思路就是连续的0或者1只可能出现在左面或者最右面或者序列中间,用线段是进行维护即可。具体见代码。
#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#define ll long long int
const int mod=10007;
using namespace std;
struct node
{
int l,r,lmax1,rmax1,sum1,sum0,lmax0,rmax0,lian1,lian0,tag,tagev;
}t[400010];
int a[100010];
void pushdown(int ri)
{
t[ri].sum0=t[ri<<1].sum0+t[ri<<1|1].sum0;
t[ri].sum1=t[ri<<1].sum1+t[ri<<1|1].sum1;
t[ri].lmax0=(t[ri<<1].lmax0==t[ri<<1].r-t[ri<<1].l+1?t[ri<<1].lmax0+t[ri<<1|1].lmax0:t[ri<<1].lmax0);
t[ri].rmax0=(t[ri<<1|1].rmax0==t[ri<<1|1].r-t[ri<<1|1].l+1?t[ri<<1|1].rmax0+t[ri<<1].rmax0:t[ri<<1|1].rmax0);
t[ri].lmax1=(t[ri<<1].lmax1==t[ri<<1].r-t[ri<<1].l+1?t[ri<<1].lmax1+t[ri<<1|1].lmax1:t[ri<<1].lmax1);
t[ri].rmax1=(t[ri<<1|1].rmax1==t[ri<<1|1].r-t[ri<<1|1].l+1?t[ri<<1|1].rmax1+t[ri<<1].rmax1:t[ri<<1|1].rmax1);
t[ri].lian0=max(t[ri<<1].lian0,max(t[ri<<1|1].lian0,t[ri<<1].rmax0+t[ri<<1|1].lmax0));
t[ri].lian1=max(t[ri<<1].lian1,max(t[ri<<1|1].lian1,t[ri<<1].rmax1+t[ri<<1|1].lmax1));
return;
}
void build(int l,int r,int ri)
{
t[ri].tag=t[ri].tagev=0;
t[ri].l=l;
t[ri].r=r;
if(l==r)
{
if(a[l]==0)
{
t[ri].lian0=t[ri].lmax0=t[ri].rmax0=t[ri].sum0=1;
t[ri].lian1=t[ri].lmax1=t[ri].rmax1=t[ri].sum1=0;
}
else
{
t[ri].lian0=t[ri].lmax0=t[ri].rmax0=t[ri].sum0=0;
t[ri].lian1=t[ri].lmax1=t[ri].rmax1=t[ri].sum1=1;
}
return;
}
int mid=(l+r)>>1;
build(l,mid,ri<<1);
build(mid+1,r,ri<<1|1);
pushdown(ri);
return;
}
void c0(int ri)
{
t[ri].lian0=t[ri].lmax0=t[ri].rmax0=t[ri].sum0=t[ri].r-t[ri].l+1;
t[ri].lian1=t[ri].lmax1=t[ri].rmax1=t[ri].sum1=0;
return;
}
void c1(int ri)
{
t[ri].lian0=t[ri].lmax0=t[ri].rmax0=t[ri].sum0=0;
t[ri].lian1=t[ri].lmax1=t[ri].rmax1=t[ri].sum1=t[ri].r-t[ri].l+1;
return;
}
void re(int ri)
{
swap(t[ri].lian0,t[ri].lian1);
swap(t[ri].lmax0,t[ri].lmax1);
swap(t[ri].rmax0,t[ri].rmax1);
swap(t[ri].sum1,t[ri].sum0);
return;
}
void add1(int ri);
void add0(int ri);
void reve(int ri);
void push1(int ri)
{
t[ri].tag=0;
if(t[ri].l==t[ri].r)
return;
add1(ri<<1);
add1(ri<<1|1);
return;
}
void push0(int ri)
{
t[ri].tag=0;
if(t[ri].l==t[ri].r)
return;
add0(ri<<1);
add0(ri<<1|1);
return;
}
void pushre(int ri)
{
t[ri].tagev^=1;
if(t[ri].l==t[ri].r)
return;
reve(ri<<1);
reve(ri<<1|1);
return;
}
void add1(int ri)
{
t[ri].tag=2;
t[ri].tagev=0;
c1(ri);
return;
}
void add0(int ri)
{
t[ri].tag=1;
t[ri].tagev=0;
c0(ri);
return;
}
void reve(int ri)
{
if(t[ri].tag==1)
push0(ri);
if(t[ri].tag==2)
push1(ri);
re(ri);
t[ri].tagev^=1;
return;
}
void gai0(int l,int r,int ri)
{
if(t[ri].tag==1)
push0(ri);
if(t[ri].tag==2)
push1(ri);
if(t[ri].tagev==1)
pushre(ri);
if(t[ri].l>=l&&t[ri].r<=r)
{
t[ri].lian0=t[ri].lmax0=t[ri].rmax0=t[ri].sum0=t[ri].r-t[ri].l+1;
t[ri].lian1=t[ri].lmax1=t[ri].rmax1=t[ri].sum1=0;
t[ri].tag=1;
t[ri].tagev=0;
return;
}
int mid=(t[ri].l+t[ri].r)>>1;
if(l<=mid)
gai0(l,r,ri<<1);
if(r>mid)
gai0(l,r,ri<<1|1);
pushdown(ri);
return;
}
void gai1(int l,int r,int ri)
{
if(t[ri].tag==1)
push0(ri);
if(t[ri].tag==2)
push1(ri);
if(t[ri].tagev==1)
pushre(ri);
if(t[ri].l>=l&&t[ri].r<=r)
{
t[ri].lian0=t[ri].lmax0=t[ri].rmax0=t[ri].sum0=0;
t[ri].lian1=t[ri].lmax1=t[ri].rmax1=t[ri].sum1=t[ri].r-t[ri].l+1;
t[ri].tag=2;
t[ri].tagev=0;
return;
}
int mid=(t[ri].l+t[ri].r)>>1;
if(l<=mid)
gai1(l,r,ri<<1);
if(r>mid)
gai1(l,r,ri<<1|1);
pushdown(ri);
return;
}
void gaivy(int l,int r,int ri)
{
if(t[ri].tag==1)
push0(ri);
if(t[ri].tag==2)
push1(ri);
if(t[ri].tagev==1)
pushre(ri);
if(t[ri].l>=l&&t[ri].r<=r)
{
swap(t[ri].lian0,t[ri].lian1);
swap(t[ri].lmax0,t[ri].lmax1);
swap(t[ri].rmax0,t[ri].rmax1);
swap(t[ri].sum1,t[ri].sum0);
t[ri].tagev=1;
t[ri].tag=0;
return;
}
int mid=(t[ri].l+t[ri].r)>>1;
if(l<=mid)
gaivy(l,r,ri<<1);
if(r>mid)
gaivy(l,r,ri<<1|1);
pushdown(ri);
return;
}
int qurry1(int l,int r,int ri)
{
if(t[ri].tag==1)
push0(ri);
if(t[ri].tag==2)
push1(ri);
if(t[ri].tagev==1)
pushre(ri);
if(t[ri].l>=l&&t[ri].r<=r)
{
return t[ri].sum1;
}
int mid=(t[ri].l+t[ri].r)>>1,ans=0;
if(l<=mid)
ans+=qurry1(l,r,ri<<1);
if(r>mid)
ans+=qurry1(l,r,ri<<1|1);
return ans;
}
int qurrylian1(int l,int r,int ri)
{
if(t[ri].tag==1)
push0(ri);
if(t[ri].tag==2)
push1(ri);
if(t[ri].tagev==1)
pushre(ri);
if(l<=t[ri].l&&r>=t[ri].r)
{
return t[ri].lian1;
}
int mid=(t[ri].l+t[ri].r)>>1,ans=0;
if(l<=mid&&r>mid)
{
ans+=min(mid-l+1,t[ri<<1].rmax1);
ans+=min(r-mid,t[ri<<1|1].lmax1);
}
if(l<=mid)
{
ans=max(ans,qurrylian1(l,r,ri<<1));
}
if(r>mid)
{
ans=max(ans,qurrylian1(l,r,ri<<1|1));
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
int n,i,m;
cin>>n>>m;
for(i=1;i<=n;i++)
cin>>a[i];
build(1,n,1);
while(m--)
{
int p,q,y;
cin>>y>>p>>q;
if(y==0)
{
gai0(p+1,q+1,1);
}
else if(y==1)
{
gai1(p+1,q+1,1);
}
else if(y==2)
{
gaivy(p+1,q+1,1);
}
else if(y==3)
{
cout<<qurry1(p+1,q+1,1)<<endl;
}
else
{
cout<<qurrylian1(p+1,q+1,1)<<endl;
}
}
return 0;
}