线段树 区间合并模板 --区间更新
题目: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);
}
}
}
}