https://www.luogu.org/problemnew/show/P4092
树剖 + 线段树区间修改,单点查询
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; inline int read() {int ret; scanf("%d", &ret); return ret;} int n, T; int now = 1, head[N]; struct Node {int u, v, nxt;} G[N << 1]; int fa[N], top[N], size[N], son[N], deep[N], lst[N], rst[N], tree[N], tim; int F[N << 2]; int Answer; struct Node_A{ inline void Add(int u, int v) {G[now].v = v; G[now].nxt = head[u]; head[u] = now ++;} void Dfs_1(int u, int f_, int dep) { fa[u] = f_; deep[u] = dep; size[u] = 1; for(int i = head[u]; ~ i; i = G[i].nxt) { int v = G[i].v; if(v != f_) { Dfs_1(v, u, dep + 1); size[u] += size[v]; if(size[v] > size[son[u]]) son[u] = v; } } } void Dfs_2(int u, int tp) { top[u] = tp; tree[u] = ++ tim; lst[u] = tim; if(!son[u]) {rst[u] = tim; return ;} Dfs_2(son[u], tp); for(int i = head[u]; ~ i; i = G[i].nxt) { int v = G[i].v; if(v != fa[u] and v != son[u]) Dfs_2(v, v); } rst[u] = tim; } #define lson jd << 1 #define rson jd << 1 | 1 void Build_tree(int l, int r, int jd) { if(l == r) {F[jd] = 1; return ;} int mid = (l + r) >> 1; Build_tree(l, mid, lson); Build_tree(mid + 1, r, rson); } void Down(int jd) { int imp = F[jd]; if(deep[imp] > deep[F[lson]]) F[lson] = imp; if(deep[imp] > deep[F[rson]]) F[rson] = imp; F[jd] = 0; } void Sec_G(int l, int r, int jd, int x, int y, int g) { if(x <= l and r <= y) { if(deep[F[jd]] < deep[g]) F[jd] = g; return ; } if(F[jd]) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_G(l, mid, lson, x, y, g); if(y > mid) Sec_G(mid + 1, r, rson, x, y, g); } void Poi_A(int l, int r, int jd, int x) { if(l == r) {Answer = F[jd]; return ;} if(F[jd]) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Poi_A(l, mid, lson, x); else Poi_A(mid + 1, r, rson, x); } }Tj; int main() { n = read(); T = read(); for(int i = 1; i <= n; i ++) head[i] = -1; for(int i = 1; i < n; i ++) { int u = read(), v = read(); Tj.Add(u, v); Tj.Add(v, u); } Tj.Dfs_1(1, 0, 1); Tj.Dfs_2(1, 1); Tj.Build_tree(1, n, 1); while(T --) { string s; cin >> s; if(s[0] == ‘C‘) {int x = read(); Tj.Sec_G(1, n, 1, lst[x], rst[x], x);} else {int x = read(); Tj.Poi_A(1, n, 1, tree[x]); cout << Answer << "\n";} } return 0; } /* 5 5 1 2 1 3 2 4 2 5 Q 2 C 2 Q 2 Q 5 Q 3 */