poj3667 Hotel

此题不难却易出错,很能考察思维的严谨性。

指定ll为区间内左端顶格数的连续可利用房间,rr为右端顶格数的数值,mm为区间内最长的连续可利用房间数。

在查询的时候,由于要返回最靠左的区间左端点,使得在该点右侧有长为l的可利用房间数。

那么首先有解存在当且仅当区间mm值大于等于给定长度l。

考虑区间左端点可能落在左区间也可能落在右区间。

横跨区间中点的情形特别要小心,我就是在这wa了几次。

 

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

 

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #define lson (u << 1)
  5 #define rson (u << 1 | 1)
  6 using namespace std;
  7 typedef __int64 LL;
  8 const int maxn = 5e4 + 10;
  9 struct Seg{
 10     int l, r;
 11     int lazy;
 12     int ll, mm, rr;//vacant rooms
 13 }seg[maxn << 2];
 14 int n, m, ans;
 15 
 16 void build(int u, int l, int r){
 17     seg[u].l = l, seg[u].r = r, seg[u].lazy = 0;
 18     seg[u].mm = seg[u].ll = seg[u].rr = r - l;
 19     if(r - l < 2) return;
 20     int mid = (l + r) >> 1;
 21     build(lson, l, mid);
 22     build(rson, mid, r);
 23 }
 24 
 25 void push_down(int u){
 26     if(seg[u].lazy != 0 && seg[u].r - seg[u].l > 1){
 27         if(seg[u].lazy == -1){
 28             seg[lson].lazy = seg[rson].lazy = -1;
 29             seg[lson].mm = seg[lson].rr = seg[lson].ll = seg[lson].r - seg[lson].l;
 30             seg[rson].mm = seg[rson].rr = seg[rson].ll = seg[rson].r - seg[rson].l;
 31             seg[u].lazy = 0;
 32         }else if(seg[u].lazy == 1){
 33             seg[lson].lazy = seg[rson].lazy = 1;
 34             seg[lson].mm = seg[lson].rr = seg[lson].ll = 0;
 35             seg[rson].mm = seg[rson].rr = seg[rson].ll = 0;
 36             seg[u].lazy = 0;
 37         }
 38     }
 39 }
 40 
 41 void push_up(int u){
 42     seg[u].mm = max(seg[lson].rr + seg[rson].ll, seg[lson].mm);
 43     seg[u].mm = max(seg[u].mm, seg[rson].mm);
 44     seg[u].ll = seg[lson].ll == seg[lson].r - seg[lson].l ? seg[lson].ll + seg[rson].ll : seg[lson].ll;
 45     seg[u].rr = seg[rson].rr == seg[rson].r - seg[rson].l ? seg[rson].rr + seg[lson].rr : seg[rson].rr;
 46 }
 47 
 48 void query(int u, int l, int r, int p){
 49     if(seg[u].mm < p || ans != -1) return;
 50     if(seg[u].ll >= p){
 51         ans = seg[u].l;
 52         return;
 53     }
 54     push_down(u);
 55     int mid = (l + r) >> 1;
 56     if(seg[lson].mm >= p) query(lson, l, mid, p);
 57     else if(seg[lson].rr + seg[rson].ll >= p) ans = mid - seg[lson].rr;
 58     else query(rson, mid, r, p);
 59 }
 60 
 61 void update(int u, int l, int r, int L, int R, int sg){
 62     if(l == L && R == r){
 63         if(sg == -1){
 64             seg[u].mm = seg[u].rr = seg[u].ll = r - l;
 65             seg[u].lazy = -1;
 66         }else if(sg == 1){
 67             seg[u].mm = seg[u].rr = seg[u].ll = 0;
 68             seg[u].lazy = 1;
 69         }
 70         return;
 71     }
 72     push_down(u);
 73     int mid = (l + r) >> 1;
 74     if(R <= mid) update(lson, l, mid, L, R, sg);
 75     else if(L >= mid) update(rson, mid, r, L, R, sg);
 76     else{
 77         update(lson, l, mid, L, mid, sg);
 78         update(rson, mid, r, mid, R, sg);
 79     }
 80     push_up(u);
 81 }
 82 
 83 int main(){
 84     freopen("in.txt", "r", stdin);
 85     while(~scanf("%d%d", &n, &m)){
 86         build(1, 1, n + 1);
 87         for(int i = 0, u, v, op; i < m; i++){
 88             scanf("%d", &op);
 89             if(op == 1){
 90                 scanf("%d", &u);
 91                 ans = -1;
 92                 query(1, 1, n + 1, u);
 93                 printf("%d\n",ans == -1 ? 0 : ans);
 94                 if(ans != -1) update(1, 1, n + 1, ans, ans + u, 1);
 95             }else if(op == 2){
 96                 scanf("%d%d", &u, &v);
 97                 update(1, 1, n + 1, u, u + v, -1);
 98             }
 99         }
100     }
101     return 0;
102 }
View Code

 

posted @ 2015-09-26 16:51  astoninfer  阅读(132)  评论(0编辑  收藏  举报