最大空子列
想到用lsum表示从左开始的最长空串,rsum表示从右开始的最长空串。
还要用biao标记一下
-1表示完全不覆盖
0表示有的覆盖有的不覆盖
1表示完全覆盖
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int tot=0,n,q;
struct rec
{
int lch,rch,lsum,rsum,maxf,l,r,sum,biao;
}tree[300100];
void clear()
{
memset(tree,0,sizeof(tree));
tot=0;
}
void maketree(int l,int r)
{
int now=++tot;
tree[now].l=l,tree[now].r=r,tree[now].biao=-1;
if (l==r)
{
tree[now].lsum=1;
tree[now].rsum=1;
tree[now].maxf=1;
return;
}
int mid=(l+r)>>1;
tree[now].lch=tot+1;maketree(l,mid);
tree[now].rch=tot+1;maketree(mid+1,r);
tree[now].lsum=tree[tree[now].lch].lsum+tree[tree[now].rch].lsum;
tree[now].rsum=tree[tree[now].lch].lsum+tree[tree[now].rch].lsum;
tree[now].maxf=tree[tree[now].lch].lsum+tree[tree[now].rch].lsum;
}
void updata_tree(int x)
{
int lc=tree[x].lch;
int rc=tree[x].rch;
tree[x].maxf=max(tree[lc].maxf,tree[rc].maxf);
int tmp=tree[lc].rsum+tree[rc].lsum;
tree[x].maxf=max(tree[x].maxf,tmp);
if (tree[lc].biao==-1)
tree[x].lsum=tree[lc].lsum+tree[rc].lsum;
else
tree[x].lsum=tree[lc].lsum;
if (tree[rc].biao==-1)
tree[x].rsum=tree[rc].rsum+tree[lc].rsum;
else
tree[x].rsum=tree[rc].rsum;
if (tree[lc].biao==tree[rc].biao)
tree[x].biao=tree[lc].biao;
}
void change(int x,int l,int r,int w)
{
if (tree[x].l>=l&&tree[x].r<=r)
{
if (w==-1)
{
int len=tree[x].r-tree[x].l+1;
tree[x].lsum=tree[x].rsum=tree[x].maxf=len;
}
if (w==1)
{
tree[x].lsum=tree[x].rsum=tree[x].maxf=0;
}
tree[x].biao=w;
return ;
}
if (tree[x].biao==-1)
{
tree[x].biao=0;
tree[tree[x].lch].biao=-1;
tree[tree[x].rch].biao=-1;
tree[tree[x].lch].lsum=tree[tree[x].lch].rsum=tree[tree[x].lch].maxf=tree[tree[x].lch].r-tree[tree[x].lch].l+1;
tree[tree[x].rch].lsum=tree[tree[x].rch].rsum=tree[tree[x].rch].maxf=tree[tree[x].rch].r-tree[tree[x].rch].l+1;
}
if (tree[x].biao==1)
{
tree[x].biao=0;
tree[tree[x].lch].biao=1;
tree[tree[x].rch].biao=1;
tree[tree[x].lch].lsum=tree[tree[x].lch].rsum=tree[tree[x].lch].maxf=0;
tree[tree[x].rch].lsum=tree[tree[x].rch].rsum=tree[tree[x].rch].maxf=0;
}
int mid=(tree[x].l+tree[x].r)>>1;
if (l<=mid) change(tree[x].lch,l,r,w);
if (r>mid) change(tree[x].rch,l,r,w);
updata_tree(x);
}
int main()
{
freopen("poj1823.in","r",stdin);
freopen("poj1823.out","w",stdout);
int ch=0,l,r;
clear();
scanf("%d%d",&n,&q);
maketree(1,n);
for (int i=1;i<=q;i++)
{
scanf("%d",&ch);
if (ch==3) printf("%d\n",tree[1].maxf);
if (ch==1)
{
scanf("%d%d",&l,&r);
change(1,l,l+r-1,1);
}
if (ch==2)
{
scanf("%d%d",&l,&r);
change(1,l,l+r-1,-1);
}
}
return 0;
}