Submission #1329423

#TimeUsernameProblemLanguageResultExecution timeMemory
1329423liptonekTeam Coding (EGOI24_teamcoding)C++20
100 / 100
270 ms32208 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAX_N=100005;
const int B=350;

struct DC 
{ 
    int d,count; 
};

vector<int> adj[MAX_N];

int pref[MAX_N];
int st[MAX_N];
int ed[MAX_N];
int depth[MAX_N];
int sz[MAX_N];
int heavy[MAX_N];
int node[MAX_N];
int subtree[MAX_N];

int timer=0;
int n,k;

vector<int> dn[MAX_N];
vector<int> nodes[MAX_N];

int ap[MAX_N];
int ai[MAX_N];
int counter[MAX_N];

vector<DC> cg[MAX_N];

int cur[MAX_N];

int cpv,tg;

int tc[MAX_N];
bool is[MAX_N];

void prep(int u, int d) 
{
    st[u]=++timer; 
    node[timer]=u;
    depth[u]=d; 
    sz[u]=1; 
    subtree[u]=d;
    
    dn[d].push_back(st[u]);
    
    heavy[u]=-1; 
    
    int xsz=-1;
    
    for(int v : adj[u]) 
    {
        prep(v,d+1);
    
        sz[u]+=sz[v];
        subtree[u]=max(subtree[u],subtree[v]);
    
        if(sz[v]>xsz) 
        { 
            xsz=sz[v]; 
            heavy[u]=v; 
        }
    }

    ed[u]=timer;
}

inline void add(int u) 
{
    int d=depth[u];

    if(is[d]) 
    {
        if(cur[d]<tc[d]) 
        {
            cpv++;
        }
    }

    cur[d]++;
}

inline void remove(int u) 
{
    int d=depth[u]; 
    
    cur[d]--;
    
    if(is[d]) 
    {
        if(cur[d]<tc[d]) 
        {
            cpv--;
        }
    }
}

void dsu(int u, bool keep) 
{
    for(int v : adj[u]) 
    {
        if(v!=heavy[u]) 
        {
            dsu(v,false);
        }
    }

    if(heavy[u]!=-1) 
    {
        dsu(heavy[u],true);
    }
    
    for(int v : adj[u]) 
    {
        if(v!=heavy[u])
        {
            for(int t=st[v]; t<=ed[v]; t++) 
            {
                add(node[t]);
            }
        }
    }

    add(u);
    
    if(pref[u]==tg) 
    {
        ap[u]=cpv;
    }
    
    if(!keep) 
    {
        for(int t=st[u]; t<=ed[u]; t++) 
        {
            remove(node[t]);
        }
    }
}

void dfs(int u) 
{
    int before=counter[pref[u]];

    for(int v : adj[u]) 
    {
        dfs(v);
    }

    counter[pref[u]]++;
    
    ai[u]=counter[pref[u]]-before;
}

int main() 
{
    ios_base::sync_with_stdio(0); 
    cin.tie(0);
    
    cin>>n>>k;
    
    for(int i=0; i<n; i++) 
    { 
        cin>>pref[i]; 
        
        nodes[pref[i]].push_back(i); 
    }

    for(int i=1; i<n; i++) 
    { 
        int p; 
        cin>>p; 
        
        adj[p].push_back(i); 
    }

    prep(0,0); 
    dfs(0);

    for(int g=0; g<k; g++) 
    {
        if(nodes[g].empty()) 
        {
            continue;
        }

        vector<int> dl;
        
        for(int u : nodes[g]) 
        {
            dl.push_back(depth[u]);
        }
        
        sort(dl.begin(),dl.end());
        
        for(int i=0; i<(int)dl.size(); ) 
        {
            int d=dl[i];
            int c=0;
        
            while(i<(int)dl.size() && dl[i]==d) 
            { 
                c++; 
                i++; 
            }
        
            cg[g].push_back({d,c});
        }
    }
    
    for(int g=0; g<k; g++) 
    {
        if(nodes[g].empty()) 
        {
            continue;
        }
    
        if((int)nodes[g].size()<=B) 
        {
            for(int u : nodes[g]) 
            {
                int p=0;
            
                auto it=lower_bound(cg[g].begin(),cg[g].end(),depth[u], [](const DC& a, int v)
                { 
                    return a.d<v; 
                });
            
                for(; it!=cg[g].end(); it++) 
                {
                    if(it->d>subtree[u]) 
                    {
                        break;
                    }
                
                    auto& v=dn[it->d];
                    
                    int s=upper_bound(v.begin(),v.end(),ed[u])-lower_bound(v.begin(),v.end(),st[u]);
                    
                    p+=min(s,it->count);
                }

                ap[u]=p;
            }
        } 
        else 
        {
            tg=g; 
            cpv=0;
        
            for(auto& dc : cg[g]) 
            { 
                is[dc.d]=true; 
                tc[dc.d]=dc.count; 
            }
        
            dsu(0,false);
        
            for(auto& dc : cg[g]) 
            {
                is[dc.d]=false;
            }
        }
    }

    int xp=-1;
    int ns=2e9;

    for(int i=0; i<n; i++) 
    {
        if(ap[i]>xp) 
        { 
            xp=ap[i]; 
            ns=ap[i]-ai[i]; 
        }
        else if(ap[i]==xp) 
        {
            ns=min(ns,ap[i]-ai[i]);
        }
    }

    cout<<xp<<" "<<ns<<endl;
    
    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...