Hotel

poj3667:http://poj.org/problem?id=3667

题目大意:Hotel有N(1 ≤ N ≤ 50,000)间rooms,并且所有的rooms都是连续排列在同一边,groups需要check in 房间,要求房间的编号为连续的r..r+Di-1并且r是最小的;visitors同样可能check out,并且他们每次check out都是编号为Xi ..Xi +Di-1 (1 ≤ Xi ≤ N-Di+1)的房间,题目的输入有两种样式:
    1  a     :  groups需要check in  a间编号连续的房间
    2  a   b : visitors  check out 房间,其中房间编号是 a…a+b-1要求对于每次request,输出为groups分配数目为a的房间中编号最小的房间编号
题解:用 线段树维护区间的连续最大值,最大左连续,最大右连续。查询时,如果当前节点的sum值大等于val,则看该区间的左连续,若左连续大等于val,直接返回left;否则,看左二子,如果左儿子的sum值大于等于val,则进入左儿子进行查询,如果不满足,再看左儿子的右连续+右儿子的左连续是否大等于val,若大于则直接返回左儿子右连续的起点值,否则进入右儿子进行查询。否则,返回0.如果返回的不是0,就进行区间更新。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 using namespace std;
  6 int u,v,w;
  7 int n,m;
  8 struct Node{
  9     int left;
 10     int right;
 11     int lsum,rsum,sum;
 12     int lazy;
 13 }node[50002*4];
 14  void build(int l,int r,int idx){
 15      node[idx].left=l;
 16      node[idx].right=r;
 17      node[idx].lazy=0;//lazy标记 
 18      if(l==r){
 19          node[idx].sum=node[idx].lsum=node[idx].rsum=1;
 20          return;
 21      }
 22      int mid=(l+r)/2;
 23      build(l,mid,idx<<1);
 24      build(mid+1,r,idx<<1|1);
 25      node[idx].sum=node[idx].lsum=node[idx].rsum=r-l+1;
 26 }
 27 void pushup(int idx){
 28    if(node[idx<<1].lsum==node[idx<<1].right-node[idx<<1].left+1)
 29         node[idx].lsum=node[idx<<1].lsum+node[idx<<1|1].lsum;
 30     else
 31         node[idx].lsum=node[idx<<1].lsum;
 32    if(node[idx<<1|1].rsum==node[idx<<1|1].right-node[idx<<1|1].left+1)
 33         node[idx].rsum=node[idx<<1].rsum+node[idx<<1|1].rsum;
 34      else
 35     node[idx].rsum=node[idx<<1|1].rsum;
 36     node[idx].sum=node[idx<<1].rsum+node[idx<<1|1].lsum;
 37     node[idx].sum=max(node[idx<<1].sum,max(node[idx].sum,node[idx<<1|1].sum));
 38 }
 39 void pushdown(int idx){
 40         if(node[idx].lazy==1){
 41         node[idx<<1].sum=node[idx<<1|1].sum=0;
 42         node[idx<<1].lsum=node[idx<<1].rsum=0;
 43         node[idx<<1|1].lsum=node[idx<<1|1].rsum=0;
 44         node[idx<<1].lazy=node[idx<<1|1].lazy=1;//很重要,开始忘记往下传递问题 
 45         node[idx].lazy=0;
 46       }
 47     if(node[idx].lazy==2){
 48         node[idx<<1].lsum=node[idx<<1].rsum=node[idx<<1].sum=node[idx<<1].right-node[idx<<1].left+1;
 49         node[idx<<1|1].lsum=node[idx<<1|1].rsum=node[idx<<1|1].sum=node[idx<<1|1].right-node[idx<<1|1].left+1;
 50         node[idx<<1].lazy=node[idx<<1|1].lazy=2;
 51         node[idx].lazy=0;
 52       }
 53 }
 54 void update1(int l,int r,int val,int idx){
 55     if(node[idx].left==l&&node[idx].right==r&&val==1){
 56         node[idx].sum=0;
 57         node[idx].lsum=node[idx].rsum=0;    
 58         node[idx].lazy=1;
 59         return;
 60     }
 61     if(node[idx].left==l&&node[idx].right==r&&val==0){
 62         node[idx].sum=node[idx].right-node[idx].left+1;
 63         node[idx].lsum=node[idx].rsum=node[idx].right-node[idx].left+1;
 64         node[idx].lazy=2;
 65         return;
 66     }
 67        pushdown(idx);
 68       int mid=(node[idx].right+node[idx].left)/2;
 69       if(mid>=r)update1(l,r,val,idx<<1);
 70       else if(mid<l)update1(l,r,val,idx<<1|1);
 71       else{
 72           update1(l,mid,val,idx<<1);
 73           update1(mid+1,r,val,idx<<1|1);
 74       }
 75       pushup(idx);
 76 }
 77 int update2(int val,int idx){
 78     if(node[idx].sum>=val){
 79         pushdown(idx);
 80         if(node[idx].lsum>=val){
 81            return node[idx].left;
 82         }
 83         else if(node[idx<<1].sum>=val)return update2(val,idx<<1);
 84         else if(node[idx<<1].rsum+node[idx<<1|1].lsum>=val)
 85             return node[idx<<1].right-node[idx<<1].rsum+1;
 86         else
 87            return update2(val,idx<<1|1);
 88     }
 89     else {
 90         return 0;
 91     }
 92 }
 93 int main(){
 94     scanf("%d%d",&n,&m);
 95     build(1,n,1);
 96     for(int i=1;i<=m;i++){
 97         cin>>u;
 98         if(u==1){
 99             cin>>v;
100             int ans=update2(v,1);
101             printf("%d
",ans);
102             if(ans>0)//这里不要有分好,我几次就是死在了这里 
103             update1(ans,ans+v-1,1,1);
104         }
105         else{
106             cin>>v>>w;
107             update1(v,v+w-1,0,1);
108         }
109     }
110 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3431320.html