• 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
    ",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
  • 相关阅读:
    hdu 5171(矩阵快速幂,递推)
    hdu 1316(大整数)
    hdu 5170(数学)
    hdu 5167(dfs)
    hdu 5166(水题)
    hdu 5720(贪心+区间合并)
    BestCoder 2nd Anniversary的前两题
    hdu 3065(AC自动机)
    2.3绘制构造线与射线
    查找ARP攻击源
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4840958.html
Copyright © 2020-2023  润新知