线段树——区间合并 模板

线段树 区间合并模板  --区间更新

题目:http://poj.org/problem?id=3667 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>          //区间合并 区间更新 
using namespace std;

struct node{
	int ls,rs,ms;
};
node tree[4*80000];
int lazy[4*80000];
void pushup(int cr,int l,int r){   
	tree[cr].ls=tree[cr<<1].ls;   //左端点最长连续 
	tree[cr].rs=tree[cr<<1|1].rs; //右端点最长连续 
	tree[cr].ms=max( tree[cr<<1].rs+tree[cr<<1|1].ls,max( tree[cr<<1].ms,tree[cr<<1|1].ms) ); //区间最长连续 
	int mid=(l+r)/2;
	if(tree[cr<<1].ls==mid-l+1) tree[cr].ls+=tree[cr<<1|1].ls;
	if(tree[cr<<1|1].rs==r-mid) tree[cr].rs+=tree[cr<<1].rs;
}	
void pushdown(int l,int r,int cr){  //lazy[cr]=1 表示空出房间,lazy[cr]=0 表示入驻房间 
	if(lazy[cr]!=-1){
		int mid=(l+r)/2;
		lazy[cr<<1]=lazy[cr];
		lazy[cr<<1|1]=lazy[cr];
		tree[cr<<1].rs=tree[cr<<1].ls=tree[cr<<1].ms=lazy[cr]*(mid-l+1);
		tree[cr<<1|1].ls=tree[cr<<1|1].ms=tree[cr<<1|1].rs=lazy[cr]*(r-mid);

		lazy[cr]=-1;
	}
}
void build(int l,int r,int cr){
	if(l==r){
		tree[cr].ls=tree[cr].rs=tree[cr].ms=1;
		return ;
	}
	int mid=(l+r)/2;
	build(l,mid,cr<<1);
	build(mid+1,r,cr<<1|1);
	pushup(cr,l,r);
}
void update(int l,int r,int cr,int L,int R,int val){    
	if(L==l&&R==r){
		tree[cr].ls=tree[cr].rs=tree[cr].ms=(r-l+1)*val;
		lazy[cr]=val;
		return ;
	}
	int mid=(L+R)/2;
	pushdown(L,R,cr);
	if(l<=mid) update( l,min(r,mid),cr<<1,L,mid,val );
	if(r>mid) update( max(mid+1,l),r,cr<<1|1,mid+1,R,val);
	pushup(cr,L,R);
}
int query(int L,int R,int cr,int n){ ///找到区间的左端点 
	if(L==R){
		return L;
	}
	int mid=(L+R)/2;
	pushdown(L,R,cr);
	if(tree[cr<<1].ms>=n){  //左 
		return query(L,mid,cr<<1,n);
	}
	if(tree[cr<<1|1].ls+tree[cr<<1].rs>=n){	//中 
		return mid-tree[cr<<1].rs+1;
	}
	if(tree[cr<<1|1].ms>=n){
		return query(mid+1,R,cr<<1|1,n);
	}
	return 0;
}
int main(){
	int n,m;
	while(EOF!=scanf("%d%d",&n,&m)){
		memset(lazy,-1,sizeof(lazy));
		build(1,n,1);
		for(int j=1;j<=m;j++){
			int a;
			scanf("%d",&a);
			if(a==1){
				int b;
				scanf("%d",&b);
				int pp=query(1,n,1,b);
				if(pp) {
					update(pp,pp+b-1,1,1,n,0);
				}
				printf("%d\n",pp);	
			}
			else{
				int b,c;
				scanf("%d%d",&b,&c);
				update(b,b+c-1,1,1,n,1);
			}		
		}
	}
}

  

猜你喜欢

转载自www.cnblogs.com/z-bear/p/9431983.html