题目
#include<cstdio>
#include<algorithm>
using namespace std;
#define lc o<<1
#define rc o<<1|1
const int N=5e4+10;
int n,m;
int mx[N<<2],lmax[N<<2],rmax[N<<2],lazy[N<<2];
void push_up(int o,int l,int r)
{
lmax[o]=lmax[lc];
rmax[o]=rmax[rc];
int mid=l+r>>1;
if(lmax[o]==mid-l+1)lmax[o]+=lmax[rc];
if(rmax[o]==r-mid)rmax[o]+=rmax[lc];
mx[o]=max(mx[lc],max(mx[rc],rmax[lc]+lmax[rc]));
}
void build(int o,int l,int r)
{
lazy[o]=-1;
mx[o]=lmax[o]=rmax[o]=r-l+1;
if(l==r)return;
int mid=l+r>>1;
build(lc,l,mid);build(rc,mid+1,r);
}
void push_down(int o,int l,int r)
{
if(lazy[o]==-1)return;//-1无操作
lazy[lc]=lazy[rc]=lazy[o];
int mid=l+r>>1;
if(lazy[o])//占满
{
lmax[lc]=rmax[lc]=mx[lc]=0;
lmax[rc]=rmax[rc]=mx[rc]=0;
}
else//清空
{
lmax[lc]=rmax[lc]=mx[lc]=mid-l+1;
lmax[rc]=rmax[rc]=mx[rc]=r-mid;
}
lazy[o]=-1;
}
int query(int o,int l,int r,int len)//返回第一个位置
{
if(l==r)return l;
push_down(o,l,r);
int mid=l+r>>1;
if(mx[lc]>=len)return query(lc,l,mid,len);//全在左
else if(rmax[lc]+lmax[rc]>=len)return mid-rmax[lc]+1;//横跨两边
else return query(rc,mid+1,r,len);//全在右
}
void update(int o,int l,int r,int nl,int nr,int op)//op=1占满,op=0清空
{
if(l==nl&&r==nr)
{
lazy[o]=op;
if(op)mx[o]=lmax[o]=rmax[o]=0;
else mx[o]=lmax[o]=rmax[o]=nr-nl+1;
return;
}
push_down(o,l,r);
int mid=l+r>>1;
if(nr<=mid)update(lc,l,mid,nl,nr,op);
else if(nl>mid)update(rc,mid+1,r,nl,nr,op);
else update(lc,l,mid,nl,mid,op),update(rc,mid+1,r,mid+1,nr,op);
push_up(o,l,r);
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1;i<=m;i++)
{
int op,x,y;
scanf("%d%d",&op,&x);
if(op&1)
{
if(mx[1]<x){puts("0");continue;}
y=query(1,1,n,x);
printf("%d\n",y);
update(1,1,n,y,y+x-1,1);//1表示占用
}
else
{
scanf("%d",&y);
update(1,1,n,x,x+y-1,0);//0表示清空
}
}
return 0;
}
总结
这题有点像CH4301求最大连续子段和,同样是建立一个最长空房mx,紧靠左侧的最长空房lmax,紧靠右侧的最长空房rmax,不同的只是多了个入住和退房操作。感觉类似于求一个区间的题可以这样定义数组。

本文介绍了如何使用线段树解决poj3667问题,该问题与求解最大连续子段和类似,涉及线段树在区间操作中的应用。内容包括题目描述、解题思路及线段树在处理入住和退房操作中的应用。
 线段树&spm=1001.2101.3001.5002&articleId=82380896&d=1&t=3&u=1827fd688a324198955e32b18ea378b3)
9694

被折叠的 条评论
为什么被折叠?



