根据题意来进行区间合并,和其他区间合并的题目差不多。
关键是在线段树中要了解维护哪几个量,然后主要的操作在PushUp和PushDown两个函数中完成
与其他类型的线段树的最大区别就在query中要有区间合并的过程。
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 50005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct Tree
{
int l,r;
int lazy;//延迟标记,用来标记更新 混合:-1 空:0 满:1
int lsum,msum,rsum;//分别为左儿子的最长连续段,整体的最长连续段,右儿子的最长连续段
}tree[maxn<<2];
void PushUp(int rt)
{
tree[rt].lsum=tree[rt<<1].lsum;
tree[rt].rsum=tree[rt<<1|1].rsum;
if(tree[rt].lsum==(tree[rt<<1].r-tree[rt<<1].l+1))
tree[rt].lsum+=tree[rt<<1|1].lsum;
if(tree[rt].rsum==(tree[rt<<1|1].r-tree[rt<<1|1].l+1))
tree[rt].rsum+=tree[rt<<1].rsum;
tree[rt].msum=max(tree[rt<<1].rsum+tree[rt<<1|1].lsum,max(tree[rt<<1].msum,tree[rt<<1|1].msum));
}
void PushDown(int rt)
{
if(tree[rt].lazy!=-1){
tree[rt<<1].lazy=tree[rt<<1|1].lazy=tree[rt].lazy;
tree[rt<<1].msum=tree[rt<<1].lsum=tree[rt<<1].rsum= tree[rt].lazy?0:(tree[rt<<1].r-tree[rt<<1].l+1);
tree[rt<<1|1].msum=tree[rt<<1|1].lsum=tree[rt<<1|1].rsum= tree[rt].lazy?0:(tree[rt<<1|1].r-tree[rt<<1|1].l+1);
tree[rt].lazy=-1;
}
}
void build(int l,int r,int rt)
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].lsum=tree[rt].rsum=tree[rt].msum=r-l+1;
tree[rt].lazy=-1;
if(l==r) return ;
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int x,int y,int val,int rt)
{
int l,r;
l=tree[rt].l;
r=tree[rt].r;
if(l==x&&r==y){
tree[rt].lsum=tree[rt].msum=tree[rt].rsum=val?0:r-l+1;
tree[rt].lazy=val;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(x<=m) update(x,min(m,y),val,rt<<1);
if(y>m) update(max(m+1,x),y,val,rt<<1|1);
PushUp(rt);
}
int query(int pos,int rt)
{
int l,r;
l=tree[rt].l;
r=tree[rt].r;
if(l==r){
return l;
}
PushDown(rt);
int m=(l+r)>>1;
if(tree[rt<<1].msum>=pos) return query(pos,rt<<1);
else if(tree[rt<<1].rsum+tree[rt<<1|1].lsum>=pos)
return m-tree[rt<<1].rsum+1;
else
return query(pos,rt<<1|1);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
build(1,n,1);
while(m--){
int a,b,c;
scanf("%d",&a);
if(a==1){
scanf("%d",&b);
if(tree[1].msum<b) puts("0");
else{
int p=query(b,1);
printf("%d\n",p);
update(p,p+b-1,1,1);
}
}
else{
scanf("%d%d",&b,&c);
update(b,b+c-1,0,1);
}
}
}
return 0;
}