线段树 区间合并模板 --区间更新
题目: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 ",pp); } else{ int b,c; scanf("%d%d",&b,&c); update(b,b+c-1,1,1,n,1); } } } }