题目链接http://begin.lydsy.com/JudgeOnline/problem.php?id=2879
线段树区间更新,区间查询问题。
维护以下四个域:
sum:该区间所有位置shu
lmx:该区间从左端点开始最大连续的空闲位置数
rmx:该区间从右端点开始最大连续的空闲位置数
mx:该区间最大连续的空闲位置数
显然,递归部分为:
mx[rt]=maxt(mx[rt<<1],mx[rt<<1|1],rmx[rt<<1]+lmx[rt<<1|1]);
lmx[rt]=lmx[rt<<1]==sum[rt<<1]?lmx[rt<<1]+lmx[rt<<1|1]:lmx[rt<<1];
rmx[rt]=rmx[rt<<1|1]==sum[rt<<1|1]?rmx[rt<<1]+rmx[rt<<1|1]:rmx[rt<<1|1];
查询时:
考虑往左是否可行,即是否满足mx[rt<<1]>=v
其次考虑左右子区间连续的空闲位置数是否可行,即是否满足rmx[rt<<1]+lmx[rt<<1|1]>=v
最后考虑往右是否可行即可
具体代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
template <class T>
T maxt(T a,T b,T c){
return max(max(a,b),c);
}
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=5e4+10;
int T,n,m;
int sum[maxn<<2],lmx[maxn<<2],rmx[maxn<<2],mx[maxn<<2];
int lazy[maxn<<2];
bool flag;
void change(int rt,int tag){
int k=(tag==1?0:1);
lazy[rt]=tag;
lmx[rt]=rmx[rt]=mx[rt]=k*sum[rt];
}
void PushUp(int rt){
mx[rt]=maxt(mx[rt<<1],mx[rt<<1|1],rmx[rt<<1]+lmx[rt<<1|1]);
lmx[rt]=lmx[rt<<1]==sum[rt<<1]?lmx[rt<<1]+lmx[rt<<1|1]:lmx[rt<<1];
rmx[rt]=rmx[rt<<1|1]==sum[rt<<1|1]?rmx[rt<<1]+rmx[rt<<1|1]:rmx[rt<<1|1];
return ;
}
void PushDown(int rt){
if(lazy[rt]!=-1){
change(rt<<1,lazy[rt]);
change(rt<<1|1,lazy[rt]);
lazy[rt]=-1;
}
}
void build(int rt,int l,int r){
sum[rt]=r-l+1;
lmx[rt]=rmx[rt]=mx[rt]=sum[rt];
lazy[rt]=-1;
if(l==r) return ;
int mid=(l+r)>>1;
build(lson);
build(rson);
}
void Update(int rt,int l,int r,int L,int R,int op){
int mid=(l+r)>>1;
if(L<=l&&r<=R){
change(rt,op);
return ;
}
PushDown(rt);
if(L<=mid) Update(lson,L,R,op);
if(R>mid) Update(rson,L,R,op);
PushUp(rt);
}
int Query(int rt,int l,int r,int v){
if(l==r) return l;
PushDown(rt);
int mid=(l+r)>>1;
if(mx[rt<<1]>=v) return Query(lson,v);
else if(rmx[rt<<1]+lmx[rt<<1|1]>=v) return mid-rmx[rt<<1]+1;
else return Query(rson,v);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
while(~scanf("%d%d",&n,&m)){
build(1,1,n);
int op,x,d;
for(int i=0;i<m;i++){
scanf("%d",&op);
if(op==1){
scanf("%d",&d);
if(mx[1]<d){
printf("0\n");
continue;
}
int ans=Query(1,1,n,d);
Update(1,1,n,ans,ans+d-1,1);
printf("%d\n",ans);
}
else{
scanf("%d%d",&x,&d);
Update(1,1,n,x,x+d-1,0);
}
}
}
return 0;
}