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

【线段树区间合并】BZOJ1593-[Usaco2008 Feb]Hotel 旅馆

时间:2016-08-03 21:58:55      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

好无聊,以前写过没什么好讲的,水过。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #define lson l,mid,rt<<1
  5 #define rson mid+1,r,rt<<1|1
  6 #define root 1
  7 using namespace std;
  8 const int MAXN=50000+50;
  9 int n,m;
 10 int lsum[MAXN<<2],rsum[MAXN<<2],msum[MAXN<<2];
 11 int cover[MAXN<<2];//区间覆盖 
 12 
 13 void pushdown(int l,int r,int rt)
 14 {
 15     int mid=(l+r)>>1;
 16     if (cover[rt]!=-1)
 17     {
 18         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
 19         if (cover[rt]==1)
 20             lsum[rt<<1]=lsum[rt<<1|1]=rsum[rt<<1]=rsum[rt<<1|1]=msum[rt<<1]=msum[rt<<1|1]=0;
 21         else
 22         {
 23             lsum[rt<<1]=rsum[rt<<1]=msum[rt<<1]=mid-l+1;
 24             lsum[rt<<1|1]=rsum[rt<<1|1]=msum[rt<<1|1]=r-mid;
 25         }
 26         cover[rt]=-1;
 27     }
 28 }
 29 
 30 void pushup(int l,int r,int rt)
 31 {
 32     int mid=(l+r)>>1;
 33     lsum[rt]=lsum[rt<<1];
 34     if (lsum[rt<<1]==(mid-l+1)) lsum[rt]+=lsum[rt<<1|1];
 35     rsum[rt]=rsum[rt<<1|1];
 36     if (rsum[rt<<1|1]==(r-mid)) rsum[rt]+=rsum[rt<<1];
 37     msum[rt]=max(rsum[rt<<1]+lsum[rt<<1|1],max(msum[rt<<1],msum[rt<<1|1]));
 38 }
 39 
 40 void update(int L,int R,int c,int l,int r,int rt)
 41 {
 42     if (L<=l && r<=R)
 43     {
 44         msum[rt]=lsum[rt]=rsum[rt]=c? 0:(r-l+1);
 45         cover[rt]=c;
 46         return;    
 47     }
 48     pushdown(l,r,rt);
 49     int mid=(l+r)>>1;
 50     if (L<=mid) update(L,R,c,lson);
 51     if (mid<R) update(L,R,c,rson);
 52     pushup(l,r,rt);    
 53 }
 54 
 55 int query(int q,int l,int r,int rt)
 56 {
 57     if (l==r) return l;
 58     pushdown(l,r,rt);
 59     int mid=(l+r)>>1;
 60     if (msum[rt<<1]>=q) return(query(q,lson));
 61     if (rsum[rt<<1]+lsum[rt<<1|1]>=q) return(mid-rsum[rt<<1]+1);
 62     return (query(q,rson));
 63 }
 64 
 65 void build(int l,int r,int rt)
 66 {
 67     lsum[rt]=rsum[rt]=msum[rt]=r-l+1;
 68     cover[rt]=-1;
 69     if (l==r) return;
 70     int mid=(l+r)>>1;
 71     build(lson);
 72     build(rson);
 73 }
 74 
 75 void solve()
 76 {
 77     build(1,n,1); 
 78     for (int i=0;i<m;i++)
 79     {
 80         int op,d,x;
 81         scanf("%d",&op);
 82         if (op==1)
 83         {
 84             scanf("%d",&d);
 85             if (msum[root]<d) puts("0");
 86             else
 87             {
 88                 x=query(d,1,n,1);
 89                 printf("%d\n",x);
 90                 update(x,x+d-1,1,1,n,1);
 91             }
 92         }
 93         else 
 94         {
 95             scanf("%d%d",&x,&d);
 96             update(x,x+d-1,0,1,n,1);
 97         }
 98     }
 99 }
100 
101 int main()
102 {
103     scanf("%d%d",&n,&m);
104     solve();
105     return 0;
106 }

 

【线段树区间合并】BZOJ1593-[Usaco2008 Feb]Hotel 旅馆

标签:

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

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