P2894 [USACO08FEB]Hotel G(线段树维护区间子串)

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*f;
}

const int maxn=2e5+100;
int n,m;
//线段树维护区间内最长的连续空房
//二分位置
int c[maxn<<2],lz[maxn<<2],pre[maxn<<2],suf[maxn<<2];
void pushup (int i,int l,int r) {
	int mid=(l+r)>>1;
	c[i]=max(c[i<<1],c[i<<1|1]);
	pre[i]=pre[i<<1];
	suf[i]=suf[i<<1|1];
	c[i]=max(c[i],pre[i<<1|1]+suf[i<<1]);
	if (pre[i<<1]==mid-l+1) pre[i]+=pre[i<<1|1];
	if (suf[i<<1|1]==r-mid) suf[i]+=suf[i<<1];
	c[i]=max(c[i],pre[i]);
	c[i]=max(c[i],suf[i]);
}
void pushdown (int i,int l,int r) {
	int mid=(l+r)>>1;
	if (lz[i]==1) {
		c[i<<1]=pre[i<<1]=suf[i<<1]=mid-l+1;
		lz[i<<1]=lz[i];
		c[i<<1|1]=pre[i<<1|1]=suf[i<<1|1]=r-mid;
		lz[i<<1|1]=lz[i];
		lz[i]=0;
	}
	else if (lz[i]==-1) {
		c[i<<1]=pre[i<<1]=suf[i<<1]=0;
		lz[i<<1]=lz[i];
		c[i<<1|1]=pre[i<<1|1]=suf[i<<1|1]=0;
		lz[i<<1|1]=lz[i];
		lz[i]=0;
	}
}
void build (int i,int l,int r) {
	if (l==r) {
		c[i]=pre[i]=suf[i]=1;
		return;
	}
	int mid=(l+r)>>1;
	build(i<<1,l,mid);
	build(i<<1|1,mid+1,r);
	pushup(i,l,r);
} 
void up (int i,int l,int r,int L,int R) {
	if (l>=L&&r<=R) {
		c[i]=pre[i]=suf[i]=r-l+1;
		lz[i]=1;
		return;
	}
	pushdown(i,l,r);
	int mid=(l+r)>>1;
	if (L<=mid) up(i<<1,l,mid,L,R);
	if (R>mid) up(i<<1|1,mid+1,r,L,R);
	pushup(i,l,r);
}
void up1 (int i,int l,int r,int L,int R) {
	if (l>=L&&r<=R) {
		c[i]=pre[i]=suf[i]=0;
		lz[i]=-1;
		return;
	}
	pushdown(i,l,r);
	int mid=(l+r)>>1;
	if (L<=mid) up1(i<<1,l,mid,L,R);
	if (R>mid) up1(i<<1|1,mid+1,r,L,R);
	pushup(i,l,r);
}
int query (int i,int l,int r,int x) {
	pushdown(i,l,r);
	if (l==r) return l;
	int mid=(l+r)>>1;
	if (c[i<<1]>=x) return query(i<<1,l,mid,x);
	else if (suf[i<<1]+pre[i<<1|1]>=x) return mid-suf[i<<1]+1;
	else return query(i<<1|1,mid+1,r,x);
}

int main () {
	n=read();
	m=read();
	build(1,1,n);
	while (m--) {
		int op=read();
		if (op==1) {
			int x=read();
			if (c[1]<x) {
				printf("0\n");
				continue;
			}
			else {
				int ans=query(1,1,n,x);
				printf("%d\n",ans);
				up1(1,1,n,ans,ans+x-1);
			}
		}
		else {
			int x=read();
			int y=read();
			up(1,1,n,x,x+y-1);
		}
	}
} 
posted @ 2021-05-23 19:27  zlc0405  阅读(49)  评论(0编辑  收藏  举报