怪异做法求助

CF343D Water Tree

代码贴 $2$ 楼了。 ```cpp #pragma GCC optimize(2) #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <cmath> using namespace std; const int N = 1000010, M = 50010; // 两种 lazy-tag // 1. 子树修改 mt(u) (modify-tree) // 2. 路径修改 mp(u) (modify-path) struct Query { int op, u; }; vector<Query> Q; vector<int> vec[M]; int f[N], g[N], col[N], n, m, B; int mt[N], mp[N], h[N], e[N], ne[N], idx; int fa[N], dep[N], top[N], sz[N], son[N]; int get(int x) { return (x / B) + 1; } void add(int a, int b) { e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx; } void dfs1(int u, int F) { fa[u] = F, dep[u] = dep[F] + 1, sz[u] = 1; for (int i = h[u]; i; i = ne[i]) { int v = e[i]; if (v == F) continue; dfs1(v, u); sz[u] += sz[v]; if (sz[v] > sz[son[u]]) son[u] = v; } } void dfs2(int u, int t) { top[u] = t; if (son[u]) dfs2(son[u], t); for (int i = h[u]; i; i = ne[i]) { int v = e[i]; if (v == fa[u] or v == son[u]) continue; dfs2(v, v); } } int lca(int u, int v) { while (top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) swap(u, v); u = fa[top[u]]; } if (dep[u] > dep[v]) swap(u, v); return u; } void dfs(int u, int F) { f[u] = max(f[u], mt[u]); g[u] = max(g[u], mp[u]); for (int i = h[u]; i; i = ne[i]) { int v = e[i]; if (v == F) continue; f[v] = max(f[v], f[u]); dfs(v, u); g[u] = max(g[u], g[v]); } } void modify(int c) { // 修改第 c 块 for (auto i : vec[c]) { int op = Q[i].op, u = Q[i].u; if (op == 1) mt[u] = i; if (op == 2) mp[u] = i; } dfs(1, 0); for (int i = 1; i <= n; i ++ ) if (f[i] > g[i]) col[i] = 1; else col[i] = 0; } void query(int c) { auto &t = vec[c]; for (int i = 0; i < t.size(); i ++ ) { int op = Q[t[i]].op, u = Q[t[i]].u; if (op == 3) printf("%d\n", col[u]); if (op == 2) { for (int j = i + 1; j < t.size(); j ++ ) { int oq = Q[t[j]].op, v = Q[t[j]].u; if (oq == 3 and lca(u, v) == v) col[v] = 0; } } if (op == 1) { for (int j = i + 1; j < t.size(); j ++ ) { int oq = Q[t[j]].op, v = Q[t[j]].u; if (oq == 3 and lca(u, v) == u) col[v] = 1; } } } } int main() { scanf("%d", &n); Q.push_back({0, 0}); for (int i = 1; i < n; i ++ ) { int a, b; scanf("%d%d", &a, &b); add(a, b), add(b, a); } scanf("%d", &m); for (int i = 1; i <= m; i ++ ) { int op, u; scanf("%d%d", &op, &u); Q.push_back({op, u}); } B = max(1, (int)sqrt((double)m / log2(n))); for (int i = 1; i <= m; i ++ ) vec[get(i)].push_back(i); dep[1] = 1; dfs1(1, 0); dfs2(1, 1); for (int i = get(1); i <= get(m); i ++ ) query(i), modify(i); return 0; } ```
by Link_Cut_Y @ 2023-09-22 21:30:05


@[Link_Cut_Y](/user/519384) lca换成倍增试试
by sxy2012yutiti @ 2023-09-22 21:43:21


@[sxy2012yutiti](/user/729386) 哥你别啊,倍增比树剖慢啊。
by Link_Cut_Y @ 2023-09-22 21:44:50


@[Link_Cut_Y](/user/519384) 噢,没学过树剖
by sxy2012yutiti @ 2023-09-22 21:45:46


代码没怎么看懂,但是st表是不是可以o1 lca,(只是看到了lca想起来的可能毫无帮助)
by 天才颓废学家 @ 2023-09-22 22:24:40


确实啊,为啥不用 $O(1)$ LCA
by Lagerent @ 2023-09-23 07:22:53


@[Lagerent](/user/477674) 艹,不会写四毛子。
by RegisterFault @ 2023-09-23 07:28:00


|