zoukankan      html  css  js  c++  java
  • UOJ 407(IOI2018 D1T3)

    给定一张$n$个点,$m$条边的无向连通图以及$q$次询问,每次询问给出$S,E,L,R$,问你是否能从$S$出发,不经过编号小于$L$的点到达某个编号大于等于$L$且小于等于$R$的点,此时切换状态,不经过编号大于$R$的点到达$E$。

    $$nle200000,mle400000,qle200000$$

    这种有限制的连通性问题一般考虑Kruskal重构树,对两个限制建出两棵树,倍增找出每个询问能到达的点的区间,然后就是一个经典的二维数点问题了,排序后树状数组解决。

      1 constexpr int MAXN = 200000 + 5, MAXM = 400000 + 5, LOG = 20;
      2 
      3 int lg[MAXN * 2];
      4 
      5 struct Tree {
      6   static constexpr int MAX_N = MAXM;
      7 
      8   int hed[MAX_N], nxt[MAX_N * 2], to[MAX_N * 2], val[MAX_N], fa[LOG][MAX_N], dep[MAX_N], L[MAX_N], R[MAX_N], cnt, num;
      9 
     10   void addEdge(int u, int v) {
     11     ++ cnt;
     12     to[cnt] = v;
     13     nxt[cnt] = hed[u];
     14     hed[u] = cnt;
     15   }
     16 
     17   void DFS(int u, int total) {
     18     for (int i = 1; 1 << i <= dep[u]; ++ i) {
     19       fa[i][u] = fa[i - 1][fa[i - 1][u]];
     20     }
     21     if (u <= total) {
     22       L[u] = R[u] = ++ num;
     23     } else {
     24       L[u] = INF, R[u] = 0;
     25     }
     26     for (int e = hed[u]; e; e = nxt[e]) {
     27       int v = to[e];
     28       if (v != fa[0][u]) {
     29         fa[0][v] = u;
     30         dep[v] = dep[u] + 1;
     31         DFS(v, total);
     32         chkmin(L[u], L[v]);
     33         chkmax(R[u], R[v]);
     34       }
     35     }
     36   }
     37 
     38   int find(int u, int w, const std::function<bool(int, int)> &comp) {
     39     Rep(i, lg[dep[u]], 0) {
     40       if (fa[i][u] && comp(val[fa[i][u]], w)) {
     41         u = fa[i][u];
     42       }
     43     }
     44     return u;
     45   }
     46 } T1, T2;
     47 
     48 struct DSU {
     49   int fa[MAXN], bel[MAXN];
     50 
     51   void init(int n) {
     52     For(i, 1, n) {
     53       fa[i] = bel[i] = i;
     54     }
     55   }
     56 
     57   int find(int u) {
     58     return fa[u] == u ? u : fa[u] = find(fa[u]);
     59   }
     60 
     61   bool same(int u, int v) {
     62     return find(u) == find(v);
     63   }
     64 
     65   void merge(int u, int v, int x) {
     66     if (!same(u, v)) {
     67       fa[fa[v]] = fa[u], bel[fa[u]] = x;
     68     }
     69   }
     70 } U;
     71 
     72 struct BinaryIndexedTree {
     73   int a[MAXN], length;
     74 
     75 #define lowbit(x) ((x) & -(x))
     76   void init(int n) {
     77     length = n;
     78   }
     79 
     80   void modify(int i, int x) {
     81     for (; i <= length; i += lowbit(i)) {
     82       a[i] += x;
     83     }
     84   }
     85 
     86   int query(int i) {
     87     int result = 0;
     88     for (; i; i -= lowbit(i)) {
     89       result += a[i];
     90     }
     91     return result;
     92   }
     93 #undef lowbit
     94 } BIT;
     95 
     96 IL void adjust(std::vector<int> &v) {
     97   for (auto &x : v) {
     98     ++ x;
     99   }
    100 }
    101 
    102 std::vector<int> check_validity(int N, std::vector<int> X, std::vector<int> Y,
    103                                 std::vector<int> S, std::vector<int> E,
    104                                 std::vector<int> L, std::vector<int> R) {
    105   adjust(X), adjust(Y), adjust(S), adjust(E), adjust(L), adjust(R);
    106   std::vector<std::pair<int, int>> edge(X.size());
    107   FOR(i, 0, (int)edge.size()) {
    108     edge[i] = std::make_pair(X[i], Y[i]);
    109   }
    110   lg[0] = -1;
    111   FOR(i, 1, N << 1) {
    112     lg[i] = lg[i >> 1] + 1;
    113   }
    114   int Q = S.size();
    115   std::vector<int> answer(Q);
    116   static bool ok[MAXN];
    117   memset(ok, 1, sizeof ok);
    118   FOR(i, 0, Q) {
    119     if (S[i] < L[i] || E[i] > R[i]) {
    120       ok[i] = 0;
    121     }
    122   }
    123   static std::vector<int> left[MAXN], right[MAXN];
    124   std::sort(edge.begin(), edge.end(), [](const std::pair<int, int> &a, const std::pair<int, int> &b) -> bool {
    125     return mymin(a.first, a.second) > mymin(b.first, b.second);
    126   });
    127   U.init(N);
    128   For(i, 1, N) {
    129     T1.val[i] = i;
    130   }
    131   int cnt = 0;
    132   for (auto &x : edge) {
    133     if (!U.same(x.first, x.second)) {
    134       ++ cnt;
    135       int p = U.fa[x.first], q = U.fa[x.second];
    136       T1.val[N + cnt] = mymin(T1.val[U.bel[p]], T1.val[U.bel[q]]);
    137       T1.addEdge(U.bel[p], N + cnt);
    138       T1.addEdge(N + cnt, U.bel[p]);
    139       T1.addEdge(U.bel[q], N + cnt);
    140       T1.addEdge(N + cnt, U.bel[q]);
    141       U.merge(x.first, x.second, N + cnt);
    142     }
    143     if (cnt >= N - 1) {
    144       break;
    145     }
    146   }
    147   T1.DFS((N << 1) - 1, N);
    148   FOR(i, 0, Q) {
    149     if (!ok[i]) {
    150       continue;
    151     }
    152     int u = T1.find(S[i], L[i], [](int a, int b) -> bool {
    153       return a >= b;
    154     });
    155     left[T1.L[u]].push_back(i);
    156     right[T1.R[u]].push_back(i);
    157   }
    158   std::sort(edge.begin(), edge.end(), [](const std::pair<int, int> &a, const std::pair<int, int> &b) -> bool {
    159     return mymax(a.first, a.second) < mymax(b.first, b.second);
    160   });
    161   U.init(N);
    162   For(i, 1, N) {
    163     T2.val[i] = i;
    164   }
    165   cnt = 0;
    166   for (auto &x : edge) {
    167     if (!U.same(x.first, x.second)) {
    168       ++ cnt;
    169       int p = U.fa[x.first], q = U.fa[x.second];
    170       T2.val[N + cnt] = mymax(T2.val[U.bel[p]], T2.val[U.bel[q]]);
    171       T2.addEdge(U.bel[p], N + cnt);
    172       T2.addEdge(N + cnt, U.bel[p]);
    173       T2.addEdge(U.bel[q], N + cnt);
    174       T2.addEdge(N + cnt, U.bel[q]);
    175       U.merge(x.first, x.second, N + cnt);
    176     }
    177     if (cnt >= N - 1) {
    178       break;
    179     }
    180   }
    181   T2.DFS((N << 1) - 1, N);
    182   std::vector<std::pair<int, int>> interval(Q);
    183   FOR(i, 0, Q) {
    184     if (!ok[i]) {
    185       continue;
    186     }
    187     int u = T2.find(E[i], R[i], [](int a, int b) -> bool {
    188       return a <= b;
    189     });
    190     interval[i] = std::make_pair(T2.L[u], T2.R[u]);
    191   }
    192   static std::vector<int> point[MAXN];
    193   For(i, 1, N) {
    194     point[T1.L[i]].push_back(T2.L[i]);
    195   }
    196   BIT.init(N);
    197   For(i, 1, N) {
    198     for (auto &x : left[i]) {
    199       answer[x] = BIT.query(interval[x].second) - BIT.query(interval[x].first - 1);
    200     }
    201     for (auto &x : point[i]) {
    202       BIT.modify(x, 1);
    203     }
    204     for (auto &x : right[i]) {
    205       answer[x] = !!(BIT.query(interval[x].second) - BIT.query(interval[x].first - 1) - answer[x]);
    206     }
    207   }
    208   return answer;
    209 }
  • 相关阅读:
    NYOJ题目100 1的个数
    NYOJ题目98成绩转换
    NYOJ题目97兄弟郊游问题
    NYOJ题目96 n-1位数
    NYOJ题目77开灯问题
    NYOJ题目75日期计算
    NYOJ题目74小学生算术
    NYOJ题目65另一种阶乘问题
    NYOJ题目64鸡兔同笼
    NYOJ题目62笨小熊
  • 原文地址:https://www.cnblogs.com/sjkmost/p/10372007.html
Copyright © 2011-2022 走看看