UOJ 407(IOI2018 D1T3)

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

$$n\le200000,m\le400000,q\le200000$$

这种有限制的连通性问题一般考虑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 }

 

posted @ 2019-02-13 21:50 sjkmost 阅读(...) 评论(...) 编辑 收藏