POJ 3667 Hotel 线段树处理区间信息

题目大意:

Hotel里有N个房间,初始全为空,有两种操作

第一种找到序列中最左端的,满足连续1的个数>=d个的位置,并把这些1变成0

第二种是区间修改L,R变成1

题目分析:

就是区间合并问题,不过有些麻烦

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define maxn 50010
 7 #define lson l, m, rt << 1
 8 #define rson m + 1, r, rt << 1 | 1
 9 using namespace std;
10 struct SegTree{
11     int l,r;
12     int mi,lsum,rsum,sum,res,p;
13 }tr[maxn << 2];
14 int col[maxn << 2];
15 int n,Q;
16 inline void pushup(int rt){
17     tr[rt].sum = tr[rt << 1].sum + tr[rt << 1 | 1].sum;
18     tr[rt].lsum = tr[rt << 1].lsum + (tr[rt << 1].r - tr[rt << 1].l + 1 == tr[rt << 1].sum ? tr[rt << 1 | 1].lsum : 0);
19     tr[rt].rsum = tr[rt << 1 | 1].rsum + (tr[rt << 1 | 1].r - tr[rt << 1 | 1].l + 1 == tr[rt << 1 | 1].sum ? tr[rt << 1].rsum : 0);
20     tr[rt].mi = max(max(tr[rt << 1].mi, tr[rt << 1 | 1].mi), tr[rt << 1].rsum + tr[rt << 1 | 1].lsum);     
21     tr[rt].res = tr[rt << 1].rsum + tr[rt << 1 | 1].lsum;
22     tr[rt].p = tr[rt << 1].r - tr[rt << 1].rsum + 1;
23 }
24 inline void pushdown(int rt){
25     if(col[rt] != -1){
26         col[rt << 1] = col[rt << 1 | 1] = col[rt];
27         tr[rt << 1].lsum = tr[rt << 1].rsum = tr[rt << 1].sum = tr[rt << 1].mi = tr[rt << 1].res = (tr[rt << 1].r - tr[rt << 1].l + 1) * col[rt];
28         tr[rt << 1].p = tr[rt << 1].l;
29         tr[rt << 1 | 1].lsum = tr[rt << 1 | 1].rsum = tr[rt << 1 | 1].sum = tr[rt << 1 | 1].mi = tr[rt << 1 | 1].res = (tr[rt << 1 | 1].r - tr[rt << 1 | 1].l + 1) * col[rt];
30         tr[rt << 1 | 1].p = tr[rt << 1 | 1].l;
31         col[rt] = -1;
32     }
33 }
34 inline void build(int l,int r,int rt){
35     tr[rt].l = l, tr[rt].r = r;
36     tr[rt].lsum = tr[rt].rsum = tr[rt].sum = tr[rt].sum = 1;
37     col[rt] = -1;
38     if(l == r){
39         return;
40     }
41     int m = (l + r) >> 1;
42     build(lson);
43     build(rson);
44     pushup(rt);
45 }
46 inline void Query(int val,int l,int r,int rt,int &p){
47     if(tr[rt].lsum >= val){
48         p = tr[rt].l;
49         return;
50     }
51     pushdown(rt);
52     int m = (l + r) >> 1;
53     if(tr[rt << 1].mi >= val) Query(val, lson, p);
54     else if(tr[rt].res >= val) p = tr[rt].p;
55     else if(tr[rt << 1 | 1].mi >= val) Query(val, rson, p);
56     //pushup(rt);
57 }
58 inline void update(int L,int R,int c,int l,int r,int rt){
59     if(l >= L && r <= R){
60         tr[rt].lsum =tr[rt].res = tr[rt].rsum = tr[rt].sum = tr[rt].mi = (tr[rt].r - tr[rt].l + 1) * c;
61         tr[rt].p = tr[rt].l;
62         col[rt] = c; 
63         return;
64     }
65     pushdown(rt);
66     int m = (l + r) >> 1;
67     if(L <= m) update(L,R,c,lson);
68     if(R  > m) update(L,R,c,rson);
69     pushup(rt);
70 }
71 int main(){
72     std::ios::sync_with_stdio(false);
73     int opt, x, d, pos;
74     cin >> n >> Q;
75     build(1, n, 1);
76     for(int i = 1; i <= Q; i ++){
77         cin >> opt;
78         if(opt == 1){
79             cin >> d;
80             if(tr[1].mi < d){
81                 cout << 0 << endl;
82             }
83             else{
84                 Query(d,1,n,1,pos);
85                 cout << pos << endl;
86                 update(pos, pos + d - 1, 0, 1, n, 1);
87             }
88         }
89         else{
90             cin >> x >> d;
91             update(x, x + d - 1, 1, 1, n, 1);
92         }
93     }return 0;
94 }

 

posted on 2017-09-27 20:14  poler  阅读(124)  评论(0编辑  收藏  举报

导航