제출 #1330343

#제출 시각아이디문제언어결과실행 시간메모리
1330343fatman87878Team Coding (EGOI24_teamcoding)C++20
0 / 100
93 ms95752 KiB
#include<bits/stdc++.h>
using namespace std;
#define IOS cin.tie(nullptr)->sync_with_stdio(0),cin.exceptions(cin.failbit);
#define lb(x) (x)&-(x)
#define all(x) (x).begin(),(x).end()
#define ll long long

constexpr int maxN=1e5+5,blk = 500;

int n,k,col[maxN],in[maxN],out[maxN],cnt,dep[maxN];

vector<int> adj[maxN];

vector<tuple<int,int,int>> ask[maxN];

vector<int> grp[maxN];

int nowcol,rec[maxN];

bitset<maxN> vis;

int mx,mnopr;

inline void dfs(int now){
    in[now] = ++cnt;
    for(int i:adj[now]){
        dep[i] = dep[now]+1;
        dfs(i);
    }
    out[now] = cnt+1;
}

inline deque<int> dfs2(int now){
    deque<int> ret;
    ret.emplace_back(1);
    for(int i:adj[now]){
        auto tmp = dfs2(i);
        tmp.emplace_front(0);
        if(tmp.size()>ret.size())swap(tmp,ret);
        for(int j = 0;j<tmp.size();j++)
            ret[j] = ret[j]+tmp[j];
    }
    int res = 0,opr = 0;
    for(auto [i,v,x]:ask[now]){
        int add = min(ret[i],v);
        opr+=add-x;
        res+=add;
    }
    if(mx<res)mx = res,mnopr = opr;
    else if(mx==res&&mnopr>opr)mnopr = opr;
    return ret;
}

inline deque<pair<int,int>> dfs3(int now){
    deque<pair<int,int>> ret;
    ret.emplace_back(1,col[now]==nowcol);
    vis[now] = 1;
    for(int i:adj[now]){
        auto tmp = dfs3(i);
        tmp.emplace_front(0,0);
        if(tmp.size()>ret.size())swap(tmp,ret);
        for(int j = 0;j<tmp.size();j++)
            ret[j] = {ret[j].first+tmp[j].first,ret[j].second+tmp[j].second};
    }
    return ret;
}

int main(){
    IOS
    cin>>n>>k;
    for(int i = 0;i<n;i++)cin>>col[i],grp[col[i]].emplace_back(i);
    for(int i = 1;i<n;i++){
        int p;cin>>p;
        adj[p].emplace_back(i);
    }
    dfs(0);
    for(int i = 0;i<k;i++){
        sort(all(grp[i]),[&](int a,int b){return dep[a]<dep[b];});
        int sz = grp[i].size();
        if(sz>blk){
            fill(rec,rec+n+1,0);
            vis.reset();
            for(int j:grp[i])rec[col[j]]++;
            for(int j:grp[i])if(!vis[j]){
                nowcol = i;
                auto it = dfs3(j);
                int res = 0,opr = 0;
                for(int i = dep[j],j = 0;j<it.size();i++,j++){
                    int add = min(it[j].first,rec[i]);
                    opr+=add-it[j].second;
                    res+=add;
                }
                if(res>mx)mx = res,mnopr = opr;
                else if(mx==res&&mnopr>opr)mnopr = opr;
            }
        }
        else {
            for(int j = 0;j<sz;j++){
                int v = grp[i][j];
                for(int k = 0,num = 0,num2 = 0;k<sz;k++){
                    int u = grp[i][k];
                    if(dep[u]>=dep[v]){
                        num++;
                        if(in[u]>=in[v]&&out[u]<=out[v])num2++;
                        if(k==sz-1||dep[grp[i][k]]<dep[grp[i][k+1]])
                            ask[v].emplace_back(dep[u]-dep[v],num,num2),num = 0,num2 = 0;
                    }
                }
            }
        }
    }
    dfs2(0);
    cout<<mx<<' '<<mnopr<<'\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...