POJ - 3667 Hotel(线段树区间合并)

Posted windystreet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ - 3667 Hotel(线段树区间合并)相关的知识,希望对你有一定的参考价值。

题目链接

题意:

给定一个有$N$个车位的停车场(都在一条直线上),现在有有两种操作

$1.x $     要停连续的停$x$辆车,输出第一辆车停的位置(尽量靠前),不能就输出$0$;

$2.x,d$ 从x位置开始开走连续的$d$辆车。

思路:

一个线段树区间和问题,而且满足区间可加性,就要用到区间合并。

  1 /*
  2 *  Author: windystreet
  3 *  Date  : 2018-08-15 10:29:55
  4 *  Motto : Think twice, code once.
  5 */
  6 #include <stdio.h>
  7 #include <string.h>
  8 #include <algorithm>
  9 
 10 using namespace std;
 11 
 12 #define X first
 13 #define Y second
 14 #define eps  1e-5
 15 #define gcd __gcd
 16 #define pb push_back
 17 #define PI acos(-1.0)
 18 #define lowbit(x) (x)&(-x)
 19 #define bug printf("!!!!!
");
 20 #define mem(x,y) memset(x,y,sizeof(x))
 21 
 22 typedef long long LL;
 23 typedef long double LD;
 24 typedef pair<int,int> pii;
 25 typedef unsigned long long uLL;
 26 
 27 const int maxn = 5e4+7;
 28 const int INF  = 1<<30;
 29 const int mod  = 1e9+7;
 30 
 31 struct Tree
 32 {
 33     int l,r,lazy;
 34     int ls,rs,ms;    // 区间前缀,后缀,最大值
 35 }tree[maxn<<2];
 36 void build(int rt,int l,int r){
 37     tree[rt].r = r;tree[rt].l = l;tree[rt].lazy = -1;
 38     if(l == r){
 39         tree[rt].ms = tree[rt].ls = tree[rt].rs = 1;return;
 40     }
 41     int mid = ( l + r ) >> 1;
 42     build(rt<<1,l,mid);
 43     build(rt<<1|1,mid+1,r);
 44     tree[rt].ms = tree[rt].ls = tree[rt].rs = tree[rt<<1].ms + tree[rt<<1|1].ms;
 45 }
 46 void pushdown(int rt){
 47     if(tree[rt].lazy!=-1){                                       // 下推标记
 48         int mid = (tree[rt].r + tree[rt].l )>>1;
 49         tree[rt<<1|1].lazy = tree[rt<<1].lazy = tree[rt].lazy;
 50         tree[rt<<1].ls = tree[rt<<1].rs = tree[rt<<1].ms = (mid - tree[rt].l+1)*tree[rt].lazy;
 51         tree[rt<<1|1].ls = tree[rt<<1|1].rs = tree[rt<<1|1].ms = (tree[rt].r -mid)*tree[rt].lazy;
 52         tree[rt].lazy = -1;
 53     }
 54 }
 55 void pushup(int rt){                                              // 向上更新
 56     tree[rt].ls = tree[rt<<1].ls;
 57     tree[rt].rs = tree[rt<<1|1].rs;
 58     if(tree[rt<<1].ls == (tree[rt<<1].r - tree[rt<<1].l + 1)){    // 区间合并
 59         tree[rt].ls += tree[rt<<1|1].ls;
 60     }
 61     if(tree[rt<<1|1].rs == (tree[rt<<1|1].r - tree[rt<<1|1].l + 1)){
 62         tree[rt].rs += tree[rt<<1].rs;
 63     }
 64     tree[rt].ms = max(max(tree[rt<<1|1].ms,tree[rt<<1].ms),tree[rt<<1].rs+tree[rt<<1|1].ls);
 65 }
 66 void update(int rt,int L,int R,int l,int r,int v){
 67     if(l<=L&&R<=r){
 68         tree[rt].ls = tree[rt].rs = tree[rt].ms = v*(R - L + 1);
 69         tree[rt].lazy = v;return;
 70     }
 71     pushdown(rt);
 72     int mid = ( L + R) >>1;
 73     if(l<=mid) update(rt<<1,L,mid,l,r,v);
 74     if(r>mid)  update(rt<<1|1,mid+1,R,l,r,v);
 75     pushup(rt);
 76 }
 77 int query(int rt,int L,int R,int v){    
 78     pushdown(rt);
 79     int mid = (L + R) >>1;
 80     if(tree[rt<<1].ms>=v){                                // 尽量靠前
 81         return query(rt<<1,L,mid,v);
 82     }else if(tree[rt<<1].rs + tree[rt<<1|1].ls>=v){
 83         return mid - tree[rt<<1].rs + 1;
 84     }else{
 85         return query(rt<<1|1,mid+1,R,v);
 86     }
 87 }
 88 
 89 void solve(){
 90     int n,m,op,x,y;
 91     while(scanf("%d%d",&n,&m)!=EOF){
 92         build(1,1,n);
 93         while(m--){
 94             scanf("%d",&op);
 95             if(op==1){
 96                 scanf("%d",&x);
 97                 if(tree[1].ms<x){
 98                     puts("0");
 99                 }else{
100                     int pos = query(1,1,n,x);
101                     printf("%d
",pos);
102                     update(1,1,n,pos,pos+x-1,0);
103                 }
104                 
105             }else{
106                 scanf("%d%d",&x,&y);
107                 update(1,1,n,x,x+y-1,1);
108             }
109         }
110     }
111     
112     return;
113 }
114 
115 int main()
116 {
117  //   freopen("F:\in.txt","r",stdin);
118 //    freopen("out.txt","w",stdout);
119 //    ios::sync_with_stdio(false);
120     int t = 1;
121     //scanf("%d",&t);
122     while(t--){
123     //    printf("Case %d: ",cas++);
124         solve();
125     }
126     return 0;
127 }

 

以上是关于POJ - 3667 Hotel(线段树区间合并)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3667 Hotel(线段树+区间合并)

poj3667-Hotel-线段树-区间合并

poj 3667 Hotel (线段树+区间合并)

POJ 3667 Hotel(线段树区间合并)

POJ - 3667 Hotel(线段树区间合并)

POJ 3667 Hotel 线段树 区间合并 + Lazy-tag