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 }
  • 相关阅读:
    Get distinct count of rows in the DataSet
    单引号双引号的html转义符
    PETS Public English Test System
    Code 39 basics (39条形码原理)
    Index was outside the bounds of the array ,LocalReport.Render
    Thread was being aborted Errors
    Reportviewer Error: ASP.NET session has expired
    ReportDataSource 值不在预期的范围内
    .NET/FCL 2.0在Serialization方面的增强
    Perl像C一样强大,像awk、sed等脚本描述语言一样方便。
  • 原文地址:https://www.cnblogs.com/sjkmost/p/10372007.html
Copyright © 2011-2022 走看看