Solution
用$col$记录 数量最多的种类, $sum$记录 种类$col$ 的数量。
然后问题就是树上链修改, 求 每个节点 数量最多的种类。
用树上差分 + 线段树合并更新即可。
Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rd read() 5 using namespace std; 6 7 const int N = 1e5 + 5; 8 9 int head[N], cnt; 10 int n, m; 11 int sum[N], top[N], son[N], sz[N], f[N], dep[N]; 12 int u[N], v[N], z[N], b[N], tot, ans[N], idf[N]; 13 14 struct edge { 15 int nxt, to; 16 }e[N << 1]; 17 18 int read() { 19 int X = 0, p = 1; char c = getchar(); 20 for (; c > '9' || c < '0'; c = getchar()) 21 if (c == '-') p = -1; 22 for (; c >= '0' && c <= '9'; c = getchar()) 23 X = X * 10 + c - '0'; 24 return X * p; 25 } 26 27 void add(int u, int v) { 28 e[++cnt].to = v; 29 e[cnt].nxt = head[u]; 30 head[u] = cnt; 31 } 32 33 int fd(int x) { 34 return lower_bound(b + 1, b + 1 + tot, x) - b; 35 } 36 37 namespace SegT { 38 39 struct node { 40 int sum, col, lson, rson; 41 node() { 42 sum = col = lson = rson = 0; 43 } 44 } s[N * 50]; 45 46 int root[N]; 47 48 #define lc(p) s[p].lson 49 #define rc(p) s[p].rson 50 #define sum(p) s[p].sum 51 #define col(p) s[p].col 52 #define mid ((l + r) >> 1) 53 54 int st[N * 50], tp, qnum; 55 56 int get() { 57 if (tp) { 58 int re = st[tp]; 59 tp--; 60 return re; 61 } 62 63 else return ++qnum; 64 } 65 66 void del(int x) { 67 lc(x) = rc(x) = sum(x) = col(x) = 0; 68 st[++tp] = x; 69 } 70 71 void up(int p) { 72 if(sum(lc(p)) >= sum(rc(p))) 73 sum(p) = sum(lc(p)), col(p) = col(lc(p)); 74 else 75 sum(p) = sum(rc(p)), col(p) = col(rc(p)); 76 } 77 78 void modify(int l, int r, int pos, int d, int &x) { 79 if(!x) x = get(); 80 if (l == r) { 81 sum(x) += d; 82 if (sum(x) > 0) 83 col(x) = pos; 84 return; 85 } 86 if (pos <= mid) 87 modify(l, mid, pos, d, lc(x)); 88 else 89 modify(mid + 1, r, pos, d, rc(x)); 90 up(x); 91 } 92 93 int merge(int l, int r, int x, int y) { 94 if (!x || !y) 95 return x + y; 96 int now = get(); 97 if (l == r) { 98 sum(now) = sum(x) + sum(y); 99 if (sum(now) > 0) 100 col(now) = max(col(x), col(y)); 101 else col(now) = 0; 102 } 103 else { 104 lc(now) = merge(l, mid, lc(x), lc(y)); 105 rc(now) = merge(mid + 1, r, rc(x), rc(y)); 106 up(now); 107 } 108 del(x); del(y); 109 return now; 110 } 111 } 112 113 using namespace SegT; 114 115 namespace SP { 116 void dfs1(int x) { 117 sz[x] = 1; 118 for (int i = head[x]; i; i = e[i].nxt) { 119 int nt = e[i].to; 120 if (nt == f[x]) 121 continue; 122 f[nt] = x; 123 dep[nt] = dep[x] + 1; 124 SP::dfs1(nt); 125 sz[x] += sz[nt]; 126 if (sz[nt] > sz[son[x]]) 127 son[x] = nt; 128 } 129 } 130 131 void dfs2(int x) { 132 if (!son[x]) 133 return; 134 top[son[x]] = top[x]; 135 SP::dfs2(son[x]); 136 for (int i = head[x]; i; i = e[i].nxt) { 137 int nt = e[i].to; 138 if (nt == f[x] || nt == son[x]) 139 continue; 140 top[nt] = nt; 141 SP::dfs2(nt); 142 } 143 } 144 145 int LCA(int x, int y) { 146 for (; top[x] != top[y];) { 147 if (dep[top[x]] < dep[top[y]]) 148 swap(x, y); 149 x = f[top[x]]; 150 } 151 if (dep[x] < dep[y]) 152 swap(x, y); 153 return y; 154 } 155 156 void solve(int x) { 157 for (int i = head[x]; i; i = e[i].nxt) { 158 int nt = e[i].to; 159 if (nt == f[x]) 160 continue; 161 SP::solve(nt); 162 root[x] = merge(1, tot, root[x], root[nt]); 163 } 164 ans[x] = col(root[x]); 165 } 166 } 167 168 int main() 169 { 170 n = rd; m = rd; 171 for (int i = 1; i < n; ++i) { 172 int x = rd, y = rd; 173 add(x, y); add(y, x); 174 } 175 dep[1] = 1; 176 SP::dfs1(1); 177 top[1] = 1; 178 SP::dfs2(1); 179 for (int i = 1; i <= m; ++i) { 180 u[i] = rd; v[i] = rd; 181 z[i] = b[i] = rd; 182 } 183 tot = m; 184 sort(b + 1, b + 1 + tot); 185 tot = unique(b + 1, b + 1 + tot) - b - 1; 186 for (int i = 1; i <= tot; ++i) 187 idf[b[i]] = i; 188 for (int i = 1; i <= m; ++i) { 189 int lca = SP::LCA(u[i], v[i]); 190 modify(1, tot, idf[z[i]], 1, root[u[i]]); 191 modify(1, tot, idf[z[i]], 1, root[v[i]]); 192 modify(1, tot, idf[z[i]], -1, root[lca]); 193 modify(1, tot, idf[z[i]], -1, root[f[lca]]); 194 } 195 SP::solve(1); 196 for (int i = 1; i <= n; ++i) 197 printf("%d " ,b[ans[i]]); 198 }