P2894 [USACO08FEB]Hotel G 线段树模板

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天…

Guess you like

Origin blog.csdn.net/weixin_45446715/article/details/120836977