제출 #1346629

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

const int MAXN = 1e5 + 10;
const int SQ = 320;

int val[MAXN];

int pre[MAXN], pos[MAXN], dist[MAXN];

int tot[MAXN], cnt[MAXN], lvl[MAXN];

vector<int> adj[MAXN], vtx[MAXN], all_lvls[MAXN];

int n;

int t = 0;

void dfs_1(int v){

  pre[v] = ++t;
  all_lvls[dist[v]].push_back(pre[v]);

  for(auto u : adj[v]){
    dist[u] = dist[v] + 1;
    dfs_1(u);
  }

  pos[v] = t;

}

bool sub(int a, int b){
  return pre[b] <= pre[a] && pos[a] <= pos[b];
}

int get(int v, int d){
  return upper_bound(all_lvls[d].begin(), all_lvls[d].end(), pos[v]) - lower_bound(all_lvls[d].begin(), all_lvls[d].end(), pre[v]);
}

pair<int, int> solve_small(int k){

  pair<int, int> ret = {0, -n};

  vector<int> visited;

  for(auto v : vtx[k]){
    if(cnt[dist[v]] == 0) visited.push_back(dist[v]);
    cnt[dist[v]] ++;
  }

  for(auto v : vtx[k]){

    pair<int, int> cur = {0, 0};

    for(auto u : vtx[k]) cur.second += sub(u, v);

    for(auto d : visited){

      int aux = min(get(v, d), cnt[d]);
      
      cur.first += aux;
      cur.second -= aux;

    }

    ret = max(ret, cur);

  }

  for(auto d : visited) cnt[d] = 0;

  return ret;

}

pair<int, int> process(int s, int k){

  queue<int> q;

  q.push(s);

  vector<int> visited;

  while(!q.empty()){

    int v = q.front();
    q.pop();

    if(tot[dist[v]] == 0) visited.push_back(dist[v]);

    tot[dist[v]] ++;
    if(val[v] == k) cnt[dist[v]] ++;

    for(auto u : adj[v]) q.push(u);

  }

  pair<int, int> ret = {0, 0};

  for(auto d : visited){

    int cur = min(tot[d], lvl[d]);

    ret.first += cur;
    ret.second -= cur - cnt[d];

    tot[d] = cnt[d] = 0;

  }

  return ret;

}

pair<int, int> dfs_2(int v, int k){

  pair<int, int> ret = {0, -n};

  if(val[v] == k) return process(v, k);

  for(auto u : adj[v]) ret = max(ret, dfs_2(u, k));

  return ret;

}

pair<int, int> solve_large(int k){

  for(int i=0; i<n; i++) lvl[i] = 0;

  for(auto v : vtx[k]) lvl[dist[v]] ++;

  return dfs_2(1, k);

}

int main(){
  cin.tie(0)->sync_with_stdio(0);

  int k; cin >> n >> k;

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

  for(int i=0; i<k; i++){
    sort(vtx[i].begin(), vtx[i].end(), [&] (int a, int b){
      return pre[a] < pre[b];
    });
  }

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

  pair<int, int> ans = {0, -n};

  dfs_1(1);

  for(int i=0; i<k; i++){

    int sz = (int) vtx[i].size();

    if(sz > SQ){
      ans = max(ans, solve_large(i));
    } else ans = max(ans, solve_small(i));

  }

  cout << ans.first << " " << -ans.second << "\n";

  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...