제출 #1344508

#제출 시각아이디문제언어결과실행 시간메모리
1344508goulthenTeam Coding (EGOI24_teamcoding)C++20
100 / 100
731 ms34528 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define rep(i,a,b) for (int i = a; i <= b; i++)
#define per(i,a,b) for (int i = a; i >= b; i--)
#define pii pair<int,int>
#define pb push_back
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
#define endl '\n'

const int MAXN = 1e5+10;
const int INF = 1e18+10;
const int MOD = 1e9+7;
vector<int> g[MAXN];
int a[MAXN], par[MAXN], dep[MAXN], tin[MAXN],tout[MAXN], t=0;
int cnt[MAXN], amt[MAXN], dp[MAXN], chd[MAXN]; // ccol<=B
const int B = 360;
vector<int> invcol[MAXN];
vector<pii> lvl[MAXN];

void dfs(int u, int p = -1) {
    tin[u] = ++t;
    lvl[dep[u]].pb({tin[u], lvl[dep[u]].size()+1});
    for(int &v : g[u]) if(v!=p) {
        dep[v] = dep[u]+1;
        dfs(v,u);
        dp[u] = max(dp[u],dp[v] + 1);
    }
    tout[u] = ++t;
}

bool isch(int u, int v) {
    // is u ch v
    return tin[u] >= tin[v] && tout[u] <= tout[v];
}
vector<pii> imp;
void fimp(int u, int col = -1, int p = -1) {
    if(a[u] == col) {
        imp.pb({tin[u],u});
        col = -1;
    }
    for(int &v : g[u]) if(v!=p) {
        fimp(v,col,u);
    }
}

void solve() {
    int n,k; cin >> n >> k;
    
    rep(i,1,n) {
        cin >> a[i];
        a[i]++;

        invcol[a[i]].pb(i);
    }

    rep(i,2,n) {
        cin >> par[i];
        par[i]++;

        g[par[i]].pb(i);
    }
    dfs(1);
    rep(i,0,n) lvl[i].pb({INF,(int)lvl[i].size()+1});

    pii ans = {1,0};

    rep(cl,1,k) {
        if(invcol[cl].size() <= B) continue;
        imp.clear();
        fimp(1,cl);
        for(int &u : invcol[cl]) {
            chd[u] = 0;
        }
        rep(i,0,n) {
            cnt[i] = 0;
        }
        for(int &u : invcol[cl]) {
            cnt[dep[u]]++;
        }
        for(int &u : invcol[cl]) {
            auto it = upper_bound(all(imp), (pii){tin[u],INF});
            if(it==imp.begin()) continue;
            it--;
            if(tout[it->se] >= tout[u]) chd[it->se]++;
        }

        for(auto &[_,u] : imp) {
            int cans = 0, cch = 0;

            rep(d,dep[u],dep[u]+dp[u]) {
                amt[d] = upper_bound(all(lvl[d]), (pii){tout[u],INF})->se - lower_bound(all(lvl[d]),(pii){tin[u],0})->se;
                //cout << u << ' ' <<d << ' '<< amt[d] << ' ' <<cnt[d] << endl;
                cans += min(amt[d],cnt[d]);
                cch += min(amt[d],cnt[d]);
            }

            cch -= chd[u];

            ans = max(ans, {cans,-cch});
        }
    }
    rep(cl,1,k) {
        if(invcol[cl].size() > B) continue;
        vector<pii> ipdep;
        for(int &u : invcol[cl]) {
            ipdep.pb({dep[u],0});
        }
        sort(all(ipdep));
        ipdep.erase(unique(all(ipdep)),ipdep.end());

        for(int &u : invcol[cl]) cnt[dep[u]]++;
        for(int &u : invcol[cl]) {
            int cans = 0, cch = 0;
            for(auto &[d,amtt] : ipdep) {
                if(d <= dep[u]) continue;
                amt[d] = upper_bound(all(lvl[d]), (pii){tout[u],0})->se - lower_bound(all(lvl[d]),(pii){tin[u],0})->se;
            }
            for(int &v : invcol[cl]) {
                if(isch(v,u)) {
                    cans++;
                    amt[dep[v]]--;
                }
            }
            for(int &v : invcol[cl]) {
                if(!isch(v,u) && dep[v]>dep[u] && amt[dep[v]]) {
                    cans++;
                    cch++;
                    amt[dep[v]]--;
                }
            }

            ans = max(ans,{cans,-cch});
        }
    }
    
    cout << ans.fi << ' ' << -ans.se << endl;
}

int32_t main() {
	ios_base::sync_with_stdio(0); cin.tie(nullptr);
    int tt = 1;
    //cin >> tt;

    while (tt--) solve();
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...