• Luogu2161 [SHOI2009]会场预约-线段树


    Solution

    线段树维护 sum 表示区间内预约个数, L 表示区间最左边的预约, R 表示区间最右边的预约。

    $pushup$ 就是这样 : 

    1 void up(int nd) {
    2         sum[nd] = sum[lson] + sum[rson] - (R[lson] == L[rson] && R[lson]);
    3         L[nd] = L[lson]; R[nd] = R[rson];
    4 }

    每次查询答案类似于$pushup$。 

    考虑把旧预约删去 :

    若该次新预约 开始时间为$l$, 结束时间为$r$,是第$i$ 个预约, 则将 与该区间在右边 和 在左边相交的 旧预约的区间都用0覆盖。

    然后再把新预约的区间都用 $i$覆盖。

    $pushdown$ 和 $laz$ 数组也有些细节

    Code

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define rd read()
      5 using namespace std;
      6 
      7 const int N = 2e5 + 5;
      8 const int end = 1e5;
      9 
     10 struct met {
     11     int L, R;
     12 }in[N];
     13 
     14 int read() {
     15     int X = 0, p = 1; char c = getchar();
     16     for (; c > '9' || c < '0'; c = getchar())
     17         if (c == '-') p = -1;
     18     for (; c >= '0' && c <= '9'; c = getchar())
     19         X = X * 10 + c - '0';
     20     return X * p;
     21 }
     22 
     23 namespace SegT {
     24     int sum[N << 2], L[N << 2], R[N << 2], laz[N << 2];
     25     struct node {
     26         int sum, L, R;
     27     };
     28 #define lson nd << 1
     29 #define rson nd << 1 | 1
     30 #define mid ((l + r) >> 1)
     31     void up(int nd) {
     32         sum[nd] = sum[lson] + sum[rson] - (R[lson] == L[rson] && R[lson]);
     33         L[nd] = L[lson]; R[nd] = R[rson];
     34     }
     35 
     36     void make(int nd, int x) {
     37         sum[nd] = x ? 1 : 0; L[nd] = R[nd] = laz[nd] = x;
     38     }
     39 
     40     void down(int nd) {
     41         if (~laz[nd]) {
     42             make(lson, laz[nd]); make(rson, laz[nd]);
     43             laz[nd] = -1;
     44         }
     45     }
     46 
     47     void modify(int cl, int cr, int c, int l, int r, int nd) {
     48         if (cl <= l && r <= cr) {
     49             make(nd, c); return;
     50         }
     51         down(nd);
     52         if (mid >= cl)
     53             modify(cl, cr, c, l, mid, lson);
     54         if (mid < cr)
     55             modify(cl, cr, c, mid + 1, r, rson);
     56         up(nd);
     57     }
     58 
     59     node query(int cl, int cr ,int l, int r, int nd) {
     60         if (cl <= l && r <= cr) {
     61             node tmp;
     62             tmp.sum = sum[nd]; tmp.L = L[nd]; tmp.R = R[nd];
     63             return tmp;
     64         }
     65         node tmp, ls, rs;
     66         down(nd);
     67         if (mid >= cl && !(mid < cr))
     68             return query(cl, cr, l, mid, lson);
     69         else if (!(mid >= cl) && mid < cr)
     70             return query(cl, cr, mid + 1, r, rson);
     71         ls = query(cl, cr, l, mid, lson);
     72         rs = query(cl, cr, mid + 1, r, rson);
     73         tmp.sum = ls.sum + rs.sum - (ls.R == rs.L && ls.R);
     74         tmp.L = ls.L; tmp.R = rs.R;
     75         return tmp;
     76     }
     77 }using namespace SegT;
     78 
     79 int main()
     80 {
     81     int n = rd;
     82     memset(laz, -1, sizeof(laz));
     83     for (int i = 1; i <= n; ++i) {
     84         char ch = getchar();
     85         while (ch > 'Z' || ch < 'A') ch = getchar();
     86         if (ch == 'A') {
     87             int l = rd, r = rd;
     88             in[i].L = l; in[i].R = r;
     89             node ans = query(l, r, 1, end, 1);
     90             printf("%d
    ", ans.sum);
     91             if (ans.L) modify(in[ans.L].L, in[ans.L].R, 0, 1, end, 1);
     92             if (ans.R) modify(in[ans.R].L, in[ans.R].R, 0, 1, end, 1);
     93             modify(l, r, i, 1, end, 1);
     94         }
     95         else {
     96             node ans = query(1, end, 1, end, 1);
     97             printf("%d
    ", ans.sum);
     98         }
     99     }
    100 }
    View Code
  • 相关阅读:
    当当网首页——JS代码
    当当网首页——CSS代码
    离散与连续 分度值
    timepicker php strtotime 8hours
    w[wi].disabled = true;
    Browser Cookie Limits
    FROM_UNIXTIME(unix_timestamp), FROM_UNIXTIME(unix_timestamp,format)
    递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
    从交集角度考虑订房系统的时间连续性
    glup 压缩图片
  • 原文地址:https://www.cnblogs.com/cychester/p/9803942.html
Copyright © 2020-2023  润新知