zoukankan      html  css  js  c++  java
  • CF1080F Katya and Segments Sets

    题意:给定n个区间,每个区间有颜色。m次询问,每次询问:这n个区间中所有被包含在[x, y]这一区间中的区间,它们的颜色是否取遍了[l, r]中的所有颜色。

    强制在线。

    解:第一步是大家都熟悉的套路⑧,把这些区间按照左端点排序。

    然后从右往左加区间,用一个可持久化数据结构维护答案。

    然后我在这里就被套路住了......一般来说是线段树上x维护右端点为x的答案。但是本题要把第二维换一下。

    主席树的版本仍旧是左端点。但是线段树上每个位置维护的是该颜色的区间,结尾的最小值。

    然后查询,我们就查对应版本对应颜色区间的全体最大值是否大于y。大于y表示那个颜色无解。输出no。否则输出yes。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 300010, M = 20000010, INF = 0x7f7f7f7f;
     4 
     5 struct Node {
     6     int l, r, c;
     7     inline bool operator <(const Node &w) const {
     8         return l < w.l;
     9     }
    10 }node[N];
    11 
    12 int ls[M], rs[M], large[M], tot;
    13 int xx, q, n, lm, X[N], rt[N];
    14 
    15 void insert(int &x, int y, int p, int v, int l, int r) {
    16     if(!x || x == y) {
    17         x = ++tot;
    18         ls[x] = ls[y];
    19         rs[x] = rs[y];
    20         large[x] = large[y];
    21     }
    22     if(l == r) {
    23         large[x] = std::min(large[x], v);
    24         return;
    25     }
    26     int mid = (l + r) >> 1;
    27     if(p <= mid) insert(ls[x], ls[y], p, v, l, mid);
    28     else insert(rs[x], rs[y], p, v, mid + 1, r);
    29     large[x] = std::max(large[ls[x]], large[rs[x]]);
    30     //printf("[%d %d] large = %d 
    ", l, r, large[x]);
    31     return;
    32 }
    33 
    34 int ask(int L, int R, int l, int r, int o) {
    35     if(!o) return INF;
    36     if(L <= l && r <= R) return large[o];
    37     int mid = (l + r) >> 1, ans = -INF;
    38     if(L <= mid) ans = std::max(ans, ask(L, R, l, mid, ls[o]));
    39     if(mid < R) ans = std::max(ans, ask(L, R, mid + 1, r, rs[o]));
    40     return ans;
    41 }
    42 
    43 int main() {
    44     memset(large, 0x7f, sizeof(large));
    45     scanf("%d%d%d", &lm, &q, &n);
    46     for(int i = 1; i <= n; i++) {
    47         scanf("%d%d%d", &node[i].l, &node[i].r, &node[i].c);
    48         X[i] = node[i].l;
    49     }
    50     std::sort(node + 1, node + n + 1);
    51     std::sort(X + 1, X + n + 1);
    52     xx = std::unique(X + 1, X + n + 1) - X - 1;
    53     for(int i = n; i >= 1; i--) {
    54         node[i].l = std::lower_bound(X + 1, X + xx + 1, node[i].l) - X;
    55         /// build
    56         insert(rt[node[i].l], rt[node[i].l + 1], node[i].c, node[i].r, 1, lm);
    57         //printf("insert %d %d rt[%d] 
    ", node[i].c, node[i].r, node[i].l);
    58     }
    59 
    60     /*printf("X : ");
    61     for(int i = 1; i <= xx; i++) {
    62         printf("%d ", X[i]);
    63     }
    64     puts("");*/
    65 
    66     for(int i = 1, x, y, l, r; i <= q; i++) {
    67         scanf("%d%d%d%d", &l, &r, &x, &y);
    68         int t = std::lower_bound(X + 1, X + xx + 1, x) - X;
    69 
    70         //printf("i = %d  t = %d 
    ", i, t);
    71 
    72         if(t > xx) {
    73             printf("no
    ");
    74             //printf("ERROR 1 
    ");
    75         }
    76         else {
    77             t = ask(l, r, 1, lm, rt[t]);
    78             if(t > y) printf("no
    ");
    79             else printf("yes
    ");
    80             //printf("t = %d 
    ", t);
    81         }
    82         fflush(stdout);
    83     }
    84 
    85     return 0;
    86 }
    AC代码
  • 相关阅读:
    Intent
    What should we do next in general after collecting relevant data
    NOTE FOR Secure Friend Discovery in Mobile Social Networks
    missing pcap.h
    after building Android Source code
    plot point(one column)
    When talking to someone else, don't infer that is has been talked with others at first. It may bring repulsion to the person who is talking with you.
    进程基本知识
    Python input和raw_input的区别
    强制 code review:reviewboard+svn 的方案
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10594754.html
Copyright © 2011-2022 走看看