区间合并模板
tree[cur].left tree[cur].right 分别代表从左端点向右和从右端点向左的连续区间长度
而 tree[cur].all 则代表整个区间内最长连续区间的长度
利用区间合并 找到符合条件区间的左端点
先看当前区间的左孩子区间能否放下 再看左右孩子共有的区间能否放下 不能则在右孩子
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int l;
int r;
int laz;
int left;
int right;
int all;
};
node tree[200010];
int n;
void pushup(int cur)
{
tree[cur].left=tree[cur*2].left;
tree[cur].right=tree[cur*2+1].right;
if(tree[cur].left==tree[cur*2].r-tree[cur*2].l+1) tree[cur].left+=tree[cur*2+1].left;
if(tree[cur].right==tree[cur*2+1].r-tree[cur*2+1].l+1) tree[cur].right+=tree[cur*2].right;
tree[cur].all=max(tree[cur*2].right+tree[cur*2+1].left,max(tree[cur*2].all,tree[cur*2+1].all));
return;
}
void pushdown(int cur)
{
if(tree[cur].laz!=-1)
{
tree[cur*2].laz=tree[cur].laz;
tree[cur*2].left=(tree[cur*2].r-tree[cur*2].l+1)*tree[cur].laz;
tree[cur*2].right=(tree[cur*2].r-tree[cur*2].l+1)*tree[cur].laz;
tree[cur*2].all=(tree[cur*2].r-tree[cur*2].l+1)*tree[cur].laz;
tree[cur*2+1].laz=tree[cur].laz;
tree[cur*2+1].left=(tree[cur*2+1].r-tree[cur*2+1].l+1)*tree[cur].laz;
tree[cur*2+1].right=(tree[cur*2+1].r-tree[cur*2+1].l+1)*tree[cur].laz;
tree[cur*2+1].all=(tree[cur*2+1].r-tree[cur*2+1].l+1)*tree[cur].laz;
tree[cur].laz=-1;
}
return;
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].laz=-1;
if(l==r)
{
tree[cur].left=1;
tree[cur].right=1;
tree[cur].all=1;
return;
}
m=(l+r)/2;
build(l,m,cur*2);
build(m+1,r,cur*2+1);
pushup(cur);
return;
}
int query(int val,int cur)
{
if(tree[cur].l==tree[cur].r)
{
return tree[cur].l;
}
pushdown(cur);
if(tree[cur*2].all>=val) return query(val,cur*2);
else if(tree[cur*2].right+tree[cur*2+1].left>=val) return tree[cur*2].r-tree[cur*2].right+1;
else return query(val,cur*2+1);
}
void update(int pl,int pr,int val,int cur)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
tree[cur].laz=val;
tree[cur].left=(tree[cur].r-tree[cur].l+1)*val;
tree[cur].right=(tree[cur].r-tree[cur].l+1)*val;
tree[cur].all=(tree[cur].r-tree[cur].l+1)*val;
return;
}
pushdown(cur);
if(pl<=tree[cur*2].r) update(pl,pr,val,cur*2);
if(pr>=tree[cur*2+1].l) update(pl,pr,val,cur*2+1);
pushup(cur);
return;
}
int main()
{
int q,i,op,p,l,res;
while(scanf("%d%d",&n,&q)!=EOF)
{
build(1,n,1);
while(q--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d",&p);
if(tree[1].all<p)
{
printf("0\n");
}
else
{
res=query(p,1);
update(res,res+p-1,0,1);
printf("%d\n",res);
}
}
else
{
scanf("%d%d",&l,&p);
update(l,l+p-1,1,1);
}
}
}
return 0;
}