经典题型,注意查询的写法,我跟通常的有所不同,lr表示左右最长连续个数,len为区间最大连续个数。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <string>
#include <vector>
//#include <iostream>
using namespace std;
struct
{
int l,r,lenth,lazy;
}tree[1000100];
int build(int l,int r,int now)
{
tree[now].l=r-l+1;
tree[now].r=r-l+1;
tree[now].lenth=r-l+1;
if(l==r)
{
return 0;
}
build(l,(l+r)/2,now*2);
build((l+r)/2+1,r,now*2+1);
return 0;
}
int change(int l,int r,int now,int ll,int rr,int num)
{
if(tree[now].lazy==1)
{
tree[now*2].lazy=1;tree[now*2+1].lazy=1;
tree[now*2].l=0;tree[now*2+1].l=0;
tree[now*2].r=0;tree[now*2+1].r=0;
tree[now*2].lenth=0;tree[now*2+1].lenth=0;
tree[now].lazy=0;
}
else if(tree[now].lazy==2)
{
tree[now*2].lazy=2;tree[now*2+1].lazy=2;
tree[now*2].l=(l+r)/2-l+1;tree[now*2+1].l=(r-(l+r)/2);
tree[now*2].r=(l+r)/2-l+1;tree[now*2+1].r=(r-(l+r)/2);
tree[now*2].lenth=(l+r)/2-l+1;tree[now*2+1].lenth=(r-(l+r)/2);
tree[now].lazy=0;
}
if(ll<=l&&rr>=r)
{
tree[now].l=num*(r-l+1);
tree[now].r=num*(r-l+1);
tree[now].lenth=num*(r-l+1);
if(num==0) tree[now].lazy=1;
else tree[now].lazy=2;
return 0;
}
if(rr<=(l+r)/2)
change(l,(l+r)/2,now*2,ll,rr,num);
else if(ll>=(l+r)/2+1)
change((l+r)/2+1,r,now*2+1,ll,rr,num);
else
{
change(l,(l+r)/2,now*2,ll,rr,num);
change((l+r)/2+1,r,now*2+1,ll,rr,num);
}
if(tree[now*2].lenth==((l+r)/2-l+1))
tree[now].l=tree[now*2].lenth+tree[now*2+1].l;
else
tree[now].l=tree[now*2].l;
if(tree[now*2+1].lenth==(r-(l+r)/2))
tree[now].r=tree[now*2+1].lenth+tree[now*2].r;
else
tree[now].r=tree[now*2+1].r;
tree[now].lenth=max(tree[now].l,tree[now].r);
tree[now].lenth=max(tree[now].lenth,tree[now*2].lenth);
tree[now].lenth=max(tree[now].lenth,tree[now*2+1].lenth);
tree[now].lenth=max(tree[now].lenth,tree[now*2].r+tree[now*2+1].l);
return 0;
}
int check(int l,int r,int now,int num,int fuzhu)
{
if(tree[now].l+fuzhu>=num)
{
return l-fuzhu;
}
if(tree[now].lazy==1)
{
tree[now*2].lazy=1;tree[now*2+1].lazy=1;
tree[now*2].l=0;tree[now*2+1].l=0;
tree[now*2].r=0;tree[now*2+1].r=0;
tree[now*2].lenth=0;tree[now*2+1].lenth=0;
tree[now].lazy=0;
}
else if(tree[now].lazy==2)
{
tree[now*2].lazy=2;tree[now*2+1].lazy=2;
tree[now*2].l=(l+r)/2-l+1;tree[now*2+1].l=(r-(l+r)/2);
tree[now*2].r=(l+r)/2-l+1;tree[now*2+1].r=(r-(l+r)/2);
tree[now*2].lenth=(l+r)/2-l+1;tree[now*2+1].lenth=(r-(l+r)/2);
tree[now].lazy=0;
}
int mid=(l+r)/2;
if(tree[now*2].lenth>=num)
return check(l,mid,now*2,num,0);
else
return check(mid+1,r,now*2+1,num,tree[now*2].r);
}
int main()
{
int i,j,n,k,m,l,ans;
while(scanf("%d%d",&n,&m)!=EOF)
{
build(1,n,1);
for(i=0;i<m;i++)
{
scanf("%d",&j);
if(j==1)
{
scanf("%d",&j);
if(tree[1].lenth<j)
{
printf("0\n");
}
else
{
ans=check(1,n,1,j,0);
printf("%d\n",ans);
change(1,n,1,ans,j+ans-1,0);
}
}
else
{
scanf("%d%d",&j,&k);
change(1,n,1,j,j+k-1,1);
}
}
}
return 0;//
}