码迷,mamicode.com
首页 > 其他好文 > 详细

【区间合并线段树】BZOJ1593-安排住宿

时间:2016-07-12 19:22:41      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

【题目大意】

查询最左端的连续长度区间;或批量修改一些区间。
【思路】

区间合并线段树……复习一下。POJ上有一样的题目,我居然还借用了别人的权限号去做BZOJ,简直愚昧到没朋友[笑cry]

处理方法以前的博文里有,这里有不赘述了。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cstdlib>
  6 using namespace std;
  7 #define lson l,m,rt<<1
  8 #define rson m+1,r,rt<<1|1 
  9 const int MAXN=55555+10;
 10 int cover[MAXN<<2];//-1表示当前没有覆盖标记,1表示均覆盖为不可行,0表示均覆盖为可行 
 11 int lsum[MAXN<<2];//该区间从左起连续的可用区间长度的最大值 
 12 int msum[MAXN<<2];//该区间中连续的可用区间长度的最大值 
 13 int rsum[MAXN<<2];//该区间从右起连续的可用区间长度的最大值 
 14  
 15 void PushUp(int rt,int m)
 16 {
 17     lsum[rt]=lsum[rt<<1];
 18     if (lsum[rt]==m-(m>>1)) lsum[rt]+=lsum[rt<<1|1];
 19     rsum[rt]=rsum[rt<<1|1];
 20     if (rsum[rt]==m>>1) rsum[rt]+=rsum[rt<<1];
 21     msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]) , rsum[rt<<1]+lsum[rt<<1|1]);
 22 }
 23  
 24 void PushDown(int rt,int m) 
 25 {
 26     if (cover[rt]!=-1)
 27     {
 28         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
 29         if (cover[rt]==1)
 30         {
 31             msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=0;
 32             msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=0;
 33         }
 34         else
 35         {
 36             msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=m-(m>>1);
 37             msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=m>>1;
 38         }
 39         cover[rt]=-1;
 40     }
 41 }
 42  
 43  
 44 int query(int w,int l,int r,int rt)
 45 {
 46     if (l==r) return l;
 47     PushDown(rt,r-l+1);
 48     int m=(l+r)>>1;
 49     if (msum[rt<<1]>=w) return(query(w,lson));
 50     if (rsum[rt<<1]+lsum[rt<<1|1]>=w) return(m-rsum[rt<<1]+1);
 51     if (msum[rt<<1|1]>=w) return(query(w,rson));
 52     return 0; 
 53 }
 54  
 55 void update(int L,int R,int o,int l,int r,int rt)
 56 {
 57     if (L<=l && r<=R)
 58     {
 59         cover[rt]=o;
 60         if (o==1) msum[rt]=lsum[rt]=rsum[rt]=0;
 61             else msum[rt]=lsum[rt]=rsum[rt]=r-l+1;
 62         return;
 63     }
 64     PushDown(rt,r-l+1);//这里是l和r,不要写成L和R 
 65     int m=(l+r)>>1;
 66     if (L<=m) update(L,R,o,lson); 
 67     if (m<R)  update(L,R,o,rson);
 68     PushUp(rt,r-l+1);
 69 }
 70  
 71 void build(int l,int r,int rt)
 72 {
 73     msum[rt]=lsum[rt]=rsum[rt]=r-l+1;
 74     cover[rt]=-1;
 75     if (l==r) return;
 76     int m=(l+r)>>1;
 77     build(lson);
 78     build(rson);
 79 }
 80  
 81 int main()
 82 {
 83     int n,m;
 84     scanf("%d%d",&n,&m);
 85     build(1,n,1);
 86     for (int i=0;i<m;i++)
 87     {
 88         int op;
 89         scanf("%d",&op);
 90         if (op==1)
 91         {
 92             int w;
 93             scanf("%d",&w);
 94             if (msum[1]<w) cout<<0<<endl;
 95                 else
 96                 {
 97                     int p=query(w,1,n,1);
 98                     cout<<p<<endl;
 99                     update(p,p+w-1,1,1,n,1);
100                 }
101         }
102         else
103         {
104             int u,v;
105             scanf("%d%d",&u,&v);
106             update(u,u+v-1,0,1,n,1);
107         }
108     }
109     return 0;
110 }

 

【区间合并线段树】BZOJ1593-安排住宿

标签:

原文地址:http://www.cnblogs.com/iiyiyi/p/5664279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!