제출 #1349177

#제출 시각아이디문제언어결과실행 시간메모리
134917712345678Team Coding (EGOI24_teamcoding)C++20
100 / 100
386 ms25460 KiB
#include <bits/stdc++.h>

using namespace std;

const int nx=1e5+5, kx=1365;

int n, k, p, a[nx], lvl[nx], sz[nx], in[nx], out[nx], rv[nx], t, f[nx];
vector<int> adj[nx], g[nx];
pair<int, int> res;

void dfs(int u, int p)
{
    if (u!=p) lvl[u]=lvl[p]+1;
    sz[u]=1;
    in[u]=++t;
    rv[t]=u;
    for (auto v:adj[u]) dfs(v, u), sz[u]+=sz[v];
    out[u]=t;
}

void sacksmall(int u, bool rem)
{
    pair<int, int> hv;
    for (auto v:adj[u]) hv=max(hv, {sz[v], v});
    for (auto v:adj[u]) if (v!=hv.second) sacksmall(v, 1);
    if (hv.second) sacksmall(hv.second, 0);
    for (auto v:adj[u]) if (v!=hv.second) for (int i=in[v]; i<=out[v]; i++) f[lvl[rv[i]]]++;
    f[lvl[u]]++;
    if (g[a[u]].size()<kx)
    {
        vector<int> log;
        int cnt=0, sw=0;
        for (auto v:g[a[u]]) if (in[u]<=in[v]&&out[v]<=out[u]) cnt++, log.push_back(lvl[v]), f[lvl[v]]--;
        for (auto v:g[a[u]]) if (!(in[u]<=in[v]&&out[v]<=out[u])&&f[lvl[v]]) f[lvl[v]]--, cnt++, sw++, log.push_back(lvl[v]);
        for (auto x:log) f[x]++;
        res=max(res, {cnt, -sw});
    }
    if (rem) for (int i=in[u]; i<=out[u]; i++) f[lvl[rv[i]]]--; 
}

int cntsubtree=0, pts=0;
int cnt[nx], cap[nx];

void insert(int u, int color)
{
    if (a[u]==color) cntsubtree++;
    cap[lvl[u]]++;
    if (cnt[lvl[u]]>=cap[lvl[u]]) pts++;
}

void erase(int u, int color)
{
    if (a[u]==color) cntsubtree--;
    if (cnt[lvl[u]]>=cap[lvl[u]]) pts--;
    cap[lvl[u]]--;
}

void sacklarge(int u, bool rem, int color)
{
    pair<int, int> hv;
    for (auto v:adj[u]) hv=max(hv, {sz[v], v});
    for (auto v:adj[u]) if (v!=hv.second) sacklarge(v, 1, color);
    if (hv.second) sacklarge(hv.second, 0, color);
    for (auto v:adj[u]) if (v!=hv.second) for (int i=in[v]; i<=out[v]; i++) insert(rv[i], color);
    insert(u, color);
    if (a[u]==color) res=max(res, {pts, -(pts-cntsubtree)});
    if (rem) for (int i=in[u]; i<=out[u]; i++) erase(rv[i], color); 
    // if (rem) cout<<"c "<<cntsubtree<<'\n';
}

int main()
{
    cin.tie(NULL)->sync_with_stdio(false);
    cin>>n>>k;
    for (int i=0; i<n; i++) cin>>a[i], g[a[i]].push_back(i);
    for (int i=1; i<n; i++) cin>>p, adj[p].push_back(i);
    dfs(0, 0);
    sacksmall(0, 1);
    for (int i=0; i<k; i++) 
    {
        if (g[i].size()>=kx) 
        {
            for (auto u:g[i]) cnt[lvl[u]]++;
            sacklarge(0, 1, i);
            for (auto u:g[i]) cnt[lvl[u]]--;
        }
    }
    cout<<res.first<<' '<<-res.second<<'\n';
}
#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...