Submission #1340743

#TimeUsernameProblemLanguageResultExecution timeMemory
1340743toast12Team Coding (EGOI24_teamcoding)C++20
42 / 100
4091 ms30288 KiB
#include <bits/stdc++.h>
using namespace std;

int n;
vector<vector<int>> adj, pos;
vector<int> color, depth, en, ex;
vector<vector<int>> depth_en, depth_ex;

int cur_time = 0;

pair<int, int> solve(int color);

void dfs(int cur, int p) {
    depth[cur] = depth[p]+1;
    en[cur] = cur_time;
    depth_en[depth[cur]].push_back(en[cur]);
    for (auto e : adj[cur]) {
        cur_time++;
        dfs(e, cur);
    }
    ex[cur] = cur_time;
    depth_ex[depth[cur]].push_back(ex[cur]);
}

vector<int> roots;

int main() {
    // subtask 2: k <= 2
    int k;
    cin >> n >> k;
    adj.resize(n);
    pos.resize(k);
    color.resize(n);
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        pos[x].push_back(i);
        color[i] = x;
    }
    for (int i = 1; i < n; i++) {
        int p;
        cin >> p;
        adj[p].push_back(i);
    }
    depth.resize(n);
    en.resize(n);
    ex.resize(n);
    depth_en.resize(n);
    depth_ex.resize(n);
    depth[0] = -1;
    dfs(0, 0);
    pair<int, int> ans = {0, INT_MAX};
    for (int i = 0; i < k; i++) {
        pair<int, int> res = solve(i);
        if (res.first > ans.first) {
            ans.first = res.first;
            ans.second = res.second;
        }
        else if (res.first == ans.first) ans.second = min(ans.second, res.second);
        roots.clear();
    }
    cout << ans.first << ' ' << ans.second << '\n';
    return 0;
}

void dfs2(int cur, int p, int c) {
    if (color[cur] == c) {
        roots.push_back(cur);
        return;
    }
    for (auto e : adj[cur]) dfs2(e, cur, c);
}

vector<pair<int, int>> f;

void dfs3(int cur, int p, int c) {
    if (color[cur] == c) f[depth[cur]].first++;
    f[depth[cur]].second++;
    for (auto e : adj[cur]) dfs3(e, cur, c);
}

pair<int, int> solve(int color) {
    vector<int> freq(n);
    for (auto x : pos[color]) freq[depth[x]]++;
    // only the topmost nodes of this color will be viable roots
    dfs2(0, 0, color);
    pair<int, int> res = {0, INT_MAX};
    for (auto root : roots) {
        int cnt = 1, swaps = 0;
        f.clear();
        f.resize(n);
        dfs3(root, root, color);
        for (int j = depth[root]+1; j < n; j++) {
            if (f[j].second == 0) break;
            cnt += f[j].first;
            int outside = freq[j]-f[j].first;
            cnt += min(f[j].second-f[j].first, outside);
            swaps += min(f[j].second-f[j].first, outside);
        }
        if (cnt > res.first) {
            res.first = cnt;
            res.second = swaps;
        }
        else if (cnt == res.first) res.second = min(res.second, swaps);
    }
    return res;
}
#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...