https://www.luogu.org/problemnew/show/P2486
太难调了
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> using namespace std; const int N = 1e5 + 10; #define yxy getchar() #define lson jd << 1 #define rson jd << 1 | 1 #define RR freopen("gg.in", "r", stdin) int n, Ty, now = 1, Tim, ans; int fa[N], top[N], deep[N], size[N], son[N], head[N], tree[N], bef[N], data[N]; struct Node{int u, v, nxt;} G[N << 1]; struct Node2{ int lcol, rcol, sum, f, jd; }T[N << 2]; inline int read() { int x = 0, f = 1; char c = yxy; while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = yxy;} while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = yxy; return x * f; } inline void Add(int u, int v) { G[now].v = v; G[now].nxt = head[u]; head[u] = now ++; } void Dfs_son(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_son(v, u, dep + 1); size[u] += size[v]; if(size[son[u]] < size[v]) son[u] = v; } } } void Dfs_un(int u, int tp) { top[u] = tp; tree[u] = ++ Tim; bef[Tim] = u; if(!son[u]) return ; Dfs_un(son[u], tp); for(int i = head[u]; ~ i; i = G[i].nxt) { int v = G[i].v; if(v != fa[u] && v != son[u]) Dfs_un(v, v); } } void Update(int jd) { T[jd].sum = T[lson].sum + T[rson].sum; if(T[lson].rcol == T[rson].lcol) T[jd].sum --; T[jd].lcol = T[lson].lcol; T[jd].rcol = T[rson].rcol; return ; } void Build_tree(int l, int r, int jd) { T[jd].f = -1; T[jd].jd = jd; if(l == r) { T[jd].lcol = T[jd].rcol = data[bef[l]]; T[jd].sum = 1; return ; } int mid = (l + r) >> 1; Build_tree(l, mid, lson); Build_tree(mid + 1, r, rson); Update(jd); } void Down(int jd) { T[lson].f = T[rson].f = T[jd].f; T[lson].lcol = T[lson].rcol = T[rson].lcol = T[rson].rcol = T[jd].f; T[lson].sum = T[rson].sum = 1; T[jd].f = -1; } void Sec_G(int l, int r, int jd, int x, int y, int col) { if(x <= l && r <= y) { T[jd].f = col, T[jd].lcol = T[jd].rcol = col; T[jd].sum = 1; return ; } if(T[jd].f != -1) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_G(l, mid, lson, x, y, col); if(y > mid) Sec_G(mid + 1, r, rson, x, y, col); Update(jd); } inline void Sec_G_imp(int x, int y, int col) { int tp1 = top[x], tp2 = top[y]; while(tp1 != tp2) { if(deep[tp1] < deep[tp2]) swap(x, y), swap(tp1, tp2); Sec_G(1, n, 1, tree[tp1], tree[x], col); x = fa[tp1]; tp1 = top[x]; } if(deep[x] < deep[y]) swap(x, y); Sec_G(1, n, 1, tree[y], tree[x], col); return ; } void Sec_A(int l, int r, int jd, int x, int y) { if(x <= l && r <= y) { ans += T[jd].sum; return ; } int mid = (l + r) >> 1; if(x <= mid) Sec_A(l, mid, lson, x, y); if(y > mid) Sec_A(mid + 1, r, rson, x, y); } inline int Sec_A_imp(int x, int y) { int tp1 = top[x], tp2 = top[y], ret = 0; while(tp1 != tp2) { if(deep[tp1] < deep[tp2]) swap(x, y), swap(tp1, tp2); ans = 0; Sec_A(1, n, 1, tree[tp1], tree[x]); ret += ans; x = fa[tp1]; tp1 = top[x]; } ans = 0; if(deep[x] < deep[y]) swap(x, y); Sec_A(1, n, 1, tree[y], tree[x]); ret += ans; return ret; } int main() { RR; n = read(); Ty = read(); for(int i = 1; i <= n; i ++) data[i] = read(); for(int i = 1; i <= n; i ++) head[i] = -1; for(int i = 1; i < n; i ++) { int u = read(), v = read(); Add(u, v); Add(v, u); } Dfs_son(1, 0, 1); Dfs_un(1, 1); Build_tree(1, n, 1); while(Ty --) { string s; cin >> s; if(s[0] == ‘C‘) { int x = read(), y = read(), col = read(); Sec_G_imp(x, y, col); } else { int x = read(), y = read(); int Answer = Sec_A_imp(x, y); cout << Answer << endl; } } return 0; }