1. 程式人生 > 其它 >P2894 [USACO08FEB]Hotel G

P2894 [USACO08FEB]Hotel G

Rose

用維護區間最長連續1的方法就可以維護

但是還要維護一下最左邊,不過這問題不大

維護一個區間最長連續子段,不在意位置就可以了

然後就可以在查詢的時候,先看一看在不在左邊,在看一看在不在中間,最後看一看在不在右邊

就解決了

可見學線段樹靠背模板是不行的

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#define lll long long
using namespace std;
int n,m;
int x,y;
struct t{
	int lm;
	int rm;
	int sum;
	int l;
	int lazy;
}tr[500000];
// f=1入住 
void pushdown(int ro){
	if(tr[ro].lazy==1){
		tr[ro<<1].lm=tr[ro<<1].rm=tr[ro<<1].sum=0;
		tr[ro<<1].lazy=1;
		tr[ro<<1|1].lm=tr[ro<<1|1].rm=tr[ro<<1|1].sum=0;
		tr[ro<<1|1].lazy=1;
		tr[ro].lazy=0;
	}
	if(tr[ro].lazy==2){
		tr[ro<<1].lm=tr[ro<<1].rm=tr[ro<<1].sum=tr[ro<<1].l;
		tr[ro<<1].lazy=2;
		tr[ro<<1|1].lm=tr[ro<<1|1].rm=tr[ro<<1|1].sum=tr[ro<<1|1].l;
		tr[ro<<1|1].lazy=2;
		tr[ro].lazy=0;
	}
}
void pushup(int ro){
	tr[ro].sum=max(tr[ro<<1].sum,max(tr[ro<<1|1].sum,tr[ro<<1].rm+tr[ro<<1|1].lm));
	tr[ro].lm=tr[ro<<1].sum==tr[ro<<1].l?tr[ro<<1].sum+tr[ro<<1|1].lm:tr[ro<<1].lm;
	tr[ro].rm=tr[ro<<1|1].sum==tr[ro<<1|1].l?tr[ro<<1|1].sum+tr[ro<<1].rm:tr[ro<<1|1].rm;
}
void add(int ro,int l,int r,int L,int R,int f){
	if(L<=l&&r<=R){
		if(f==1){
			tr[ro].lm=tr[ro].rm=tr[ro].sum=0;
			tr[ro].lazy=1;
		}else{
			tr[ro].lm=tr[ro].rm=tr[ro].sum=tr[ro].l;
			tr[ro].lazy=2;
		}
		return ;
	}
	pushdown(ro);
	int mid=(l+r)>>1;
	if(L<=mid) add(ro<<1,l,mid,L,R,f);
	if(R>mid) add(ro<<1|1,mid+1,r,L,R,f);
	pushup(ro);
}
int que(int ro,int l,int r){
	if(l==r) return l;
	pushdown(ro);
	int mid=(l+r)>>1;
	if(tr[ro<<1].sum>=y){
		return que(ro<<1,l,mid);
	}else
		if(tr[ro<<1].rm+tr[ro<<1|1].lm>=y){
			return mid-tr[ro<<1].rm+1;
		}
	else{
		return que(ro<<1|1,mid+1,r);
	}
}
void ini(int ro,int l,int r){
	if(l==r){
		tr[ro].l=1;
		return ;
	}
	int mid=(l+r)>>1;
	tr[ro].l=(r-l+1);
	ini(ro<<1,l,mid);
	ini(ro<<1|1,mid+1,r);
}
int z;
int main(){
	scanf("%d%d",&n,&m);
	ini(1,1,n);
	add(1,1,n,1,n,2);
	while(m--){
		scanf("%d%d",&x,&y);
		if(x==1){
			if(tr[1].sum>=y){
				int l=que(1,1,n);
				cout<<l<<endl;
				add(1,1,n,l,l+y-1,1);
			}else{
				cout<<0<<endl;
			}
		}else{
			scanf("%d",&z);
			add(1,1,n,y,y+z-1,2);
		}
		
	}
	return 0;
}