#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int MaxN = 100000 + 5; int n, m, Index; int A[MaxN], Pos[MaxN], Col[MaxN], Son[MaxN], Father[MaxN], Top[MaxN], Size[MaxN], Depth[MaxN]; int V[MaxN * 4], Lnum[MaxN * 4], Rnum[MaxN * 4]; struct Edge { int v; Edge *Next; } E[MaxN * 2], *P = E, *Point[MaxN]; inline void AddEdge(int x, int y) { ++P; P -> v = y; P -> Next = Point[x]; Point[x] = P; } int DFS_1(int x, int Fa, int Dep) { Father[x] = Fa; Depth[x] = Dep; Size[x] = 1; int MaxSonSize, SonSize; MaxSonSize = 0; for (Edge *j = Point[x]; j; j = j -> Next) { if (j -> v == Fa) continue; SonSize = DFS(j -> v, x, Dep + 1); Size[x] += SonSize; if (SonSize > MaxSonSize) { Son[x] = j -> v; MaxSonSize = SonSize; } } return Size[x]; } void DFS_2(int x) { if (x == Son[Father[x]]) Top[x] = Top[Father[x]]; else Top[x] = x; Pos[x] = ++Index; A[Pos[x]] = Col[x]; DFS_2(Son[x]); for (Edge *j = Point[x]; j; j = j -> Next) { if (j -> v == Father[x] || j -> v == Son[x]) continue; DFS_2(j -> v); } } inline void Update(int x) { V[x] = V[x << 1] + V[x << 1 | 1]; Lnum[x] = Lnum[x << 1]; Rnum[x] = Rnum[x << 1 | 1]; if (Rnum[x << 1] == Lnum[x << 1 | 1]) --V[x]; } void BuildTree(int x, int s, int t) { if (s == t) { Lnum[x] = A[x]; Rnum[x] = A[x]; V[x] = 1; return; } int m = (s + t) >> 1; BuildTree(x << 1, s, m); BuildTree(x << 1 | 1, m + 1, t); Update(x); } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%d", &Col[i]); for (int i = 1; i <= n - 1; ++i) { scanf("%d%d", &a, &b); AddEdge(a, b); AddEdge(b, a); } Index = 0; DFS_1(1, 0, 0); DFS_2(1); BuildTree(1, 1, n); char ch; for (int i = 1; i <= m; ++i) { ch = ‘0‘; while (ch != ‘C‘ && ch != ‘Q‘) ch = getchar(); scanf("%d%d%d", &a, &b, &c); } return 0; }
时间: 2024-10-24 21:25:07