P2894 [USACO08FEB]Hotel G 线段树模板
一个非常标准的线段树+懒惰标记
建议当做模板使用
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int len[400010],sum[400010],ml[400010],mr[400010],lazy[400010];
int n,q;
void pushup(int rt) {
//tell daddy about it
if (sum[rt<<1]==len[rt<<1]) ml[rt]=sum[rt<<1]+ml[rt<<1|1];//total equals to left plus right
else ml[rt]=ml[rt<<1];//no change
if (sum[rt<<1|1]==len[rt<<1|1]) mr[rt]=sum[rt<<1|1]+mr[rt<<1];
else mr[rt]=mr[rt<<1|1];
sum[rt]=max(max(sum[rt<<1],sum[rt<<1|1]),mr[rt<<1]+ml[rt<<1|1]);//one of the biggist
return;
}
void pushdown(int rt) {
//tell kids
if (lazy[rt]==0) return;
if (lazy[rt]==1) {
//zero means no space left
lazy[rt<<1]=lazy[rt<<1|1]=1;//tell kids
sum[rt<<1]=ml[rt<<1]=mr[rt<<1]=0;
sum[rt<<1|1]=ml[rt<<1|1]=mr[rt<<1|1]=0;
}
if (lazy[rt]==2) {
//no one then all the rooms are fine to live in
lazy[rt<<1]=lazy[rt<<1|1]=2;
sum[rt<<1]=ml[rt<<1]=mr[rt<<1]=len[rt<<1];
sum[rt<<1|1]=ml[rt<<1|1]=mr[rt<<1|1]=len[rt<<1|1];
}
lazy[rt]=0;
}
void build(int l,int r,int rt) {
ml[rt]=mr[rt]=sum[rt]=len[rt]=r-l+1;//all are empty
lazy[rt]=0;//all are fine
if(l==r) return;
int m = (l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
}
void update(int l,int r,int rt,int L,int R,int c) {
//区间修改
pushdown(rt);
if (L<=l&&r<=R) {
if(c==1) sum[rt]=ml[rt]=mr[rt]=0;//one means all full
else sum[rt]=ml[rt]=mr[rt]=len[rt];//two means all empty
lazy[rt]=c;
return ;
}
int m = (l+r)>>1;
if (L<=m) update(l,m,rt<<1,L,R,c);
if (R>m) update(m+1,r,rt<<1|1,L,R,c);
pushup(rt);
}
int query(int l,int r,int rt,int x) {
//区间查询
pushdown(rt);//tell kids
if(l==r) return l;//end of everything
int m = (l+r)>>1;
if (sum[rt<<1]>=x) return query(l,m,rt<<1,x);//if there are spaces at left son...
if (mr[rt<<1]+ml[rt<<1|1]>=x) return m-mr[rt<<1]+1;//if there are only
//enough spaces at left and right son
else return query(m+1,r,rt<<1|1,x);//else it is at right son
}
int main() {
scanf("%d%d",&n,&q);
build(1,n,1);
while (q--) {
int opt,x,y,p;
scanf("%d",&opt);
if (opt==1) {
scanf("%d",&x);
if (sum[1]<x) {
//just impossible
printf("0\n");
continue;
}
p = query(1,n,1,x);
printf("%d\n",p);
update(1,n,1,p,p+x-1,1);//one means all full
} else {
scanf("%d%d",&x,&y);
update(1,n,1,x,x+y-1,2);//two means all empty
}
}
return 0;
}
CSP-J-S 2021 Rp++ 倒计时3天…