This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define mp make_pair
#define F first
#define S second
#define eb emplace_back
#define iter(a) a.begin(), a.end()
#define lsort(a) sort(iter(a))
#define gsort(a) sort(iter(a), greater<>())
#define printv(a, b) { \
    for(auto pv : a) b << pv << " "; \
    b << "\n"; \
}
using namespace std;
using pii = pair<int, int>;
int n, m;
vector<int> C;
vector<vector<int>> g;
vector<vector<int>> cv;
vector<int> pr, in, out, dpt;
vector<vector<int>> anc;
vector<int> dsu, mx, sz, top;
vector<set<int>> dc;
int ts = 0;
const int SZ = 20;
void init(){
    C.resize(n + 1);
    g.resize(n + 1);
    cv.resize(m + 1);
    pr.resize(n + 1);
    in.resize(n + 1);
    out.resize(n + 1);
    anc.resize(SZ, vector<int>(n + 1));
    dpt.resize(n + 1);
    dsu.resize(n + 1);
    iota(iter(dsu), 0);
    mx.resize(n + 1);
    dc.resize(n + 1);
    sz.resize(n + 1, 1);
    top.resize(n + 1);
    iota(iter(top), 0);
}
int findDSU(int a){
    if(dsu[a] != a) dsu[a] = findDSU(dsu[a]);
    return dsu[a];
}
void unionDSU(int a, int b){
    a = findDSU(a);
    b = findDSU(b);
    if(a == b) return;
    if(sz[a] < sz[b]) swap(a, b);
    dsu[b] = a;
    sz[a] += sz[b];
    for(int i : dc[b]) dc[a].insert(i);
    if(in[top[b]] < in[top[a]]) top[a] = top[b];
    mx[a] = max(mx[a], mx[b]);
}
void dfs(int now, int p){
    pr[now] = p;
    in[now] = ts++;
    dpt[now] = dpt[p] + 1;
    anc[0][now] = p;
    for(int i : g[now]){
        if(i == p) continue;
        dfs(i, now);
    }
    out[now] = ts++;
}
bool isAnc(int a, int b){
    return in[a] <= in[b] && out[a] >= out[b];
}
int lca(int a, int b){
    if(isAnc(a, b)) return a;
    for(int i = SZ - 1; i >= 0; i--){
        if(!isAnc(anc[i][a], b)) a = anc[i][a];
    }
    return anc[0][a];
}
int dis(int a, int b){
    int l = lca(a, b);
    return dpt[a] + dpt[b] - 2 * dpt[l];
}
int getsz(int c){
    sort(iter(cv[c]), [&](int x, int y){ return in[x] < in[y]; });
    int ans = 0;
    int rt = cv[c][0];
    for(int i : cv[c]) rt = lca(rt, i);
    int lst = rt;
    for(int i : cv[c]){
        ans += dis(lst, i);
        lst = i;
    }
    ans += dis(lst, rt);
    ans /= 2; ans++;
    return ans;
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m;
    init();
    for(int i = 1; i < n; i++){
        int u, v;
        cin >> u >> v;
        g[u].eb(v);
        g[v].eb(u);
    }
    for(int i = 1; i <= n; i++){
        cin >> C[i];
        cv[C[i]].eb(i);
        dc[i].insert(C[i]);
    }
    dfs(1, 1);
    for(int i = 1; i < SZ; i++){
        for(int j = 1; j <= n; j++){
            anc[i][j] = anc[i - 1][anc[i - 1][j]];
        }
    }
    vector<int> csz(m + 1);
    for(int i = 1; i <= m; i++) csz[i] = getsz(i);
    
    vector<int> owo(m);
    iota(iter(owo), 1);
    sort(iter(owo), [&](int x, int y){ return csz[x] < csz[y]; });
    vector<int> id(m + 1);
    for(int i = 0; i < m; i++) id[owo[i]] = i;
    for(int i = 1; i <= n; i++){
        mx[i] = id[C[i]];
    }
    //printv(owo, cerr);
    int ans = n;
    for(int i = 0; i < m; i++){
        int c = owo[i];
        //cerr << "do " << c << "\n";
        int rt = cv[c][0];
        for(int i : cv[c]) rt = lca(rt, i);
        
        for(int v : cv[c]){
            while(!isAnc(v, rt)){
                unionDSU(v, pr[v]);
                v = top[findDSU(v)];
            }
        }
        //for(int i = 1; i <= n; i++) cerr << findDSU(i) << " ";
        //cerr << "\n";
        rt = findDSU(rt);
        //cerr << "ok " << rt << " " << dc[rt].size() << " " << mx[rt] << "\n";
        if(mx[rt] == i) ans = min(ans, (int)dc[rt].size() - 1);
    }
    cout << ans << "\n";
    return 0;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |