Submission #1080364

#TimeUsernameProblemLanguageResultExecution timeMemory
1080364wiwihoTeam Coding (EGOI24_teamcoding)C++14
100 / 100
604 ms127460 KiB
#include <bits/stdc++.h> using namespace std; #define iter(v) v.begin(), v.end() #define pb emplace_back #define ff first #define ss second #define SZ(v) int(v.size()) using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; #ifdef zisk void debug() { cerr << "\n"; } template<class T, class ... U> void debug(T a, U... b) { cerr << a << " ", debug(b...); } template<class T> void pary(T l, T r){ while (l != r) cerr << *l << " ", l++; cerr << "\n"; } #else #define debug(...) void() #define pary(...) void() #endif int main() { ios_base::sync_with_stdio(false); cin.tie(0); int n, K; cin >> n >> K; const int B = 400; vector<int> color(n); vector<vector<int>> pos(K); for (int i = 0; i < n; i++) { cin >> color[i]; pos[color[i]].pb(i); } vector<vector<int>> g(n); for (int i = 1; i < n; i++) { int p; cin >> p; g[p].pb(i); } vector<int> dpt(n), in(n), out(n); int ts = 0; vector<int> cur(K, -1); vector<bool> top(n); auto dfs1 = [&](auto dfs, int now) -> void { in[now] = ts++; if (cur[color[now]] == -1) { cur[color[now]] = now; top[now] = true; } for (int i : g[now]) { dpt[i] = dpt[now] + 1; dfs(dfs, i); } if (cur[color[now]] == now) cur[color[now]] = -1; out[now] = ts++; }; dfs1(dfs1, 0); auto isAnc = [&](int a, int b) { return in[a] <= in[b] && out[b] <= out[a]; }; int ans_member = 0, ans_swp = 0; auto solve_big = [&](int c) { //debug("solve_big", c); vector<int> total(n + 1); for (int i = 0; i < n; i++) if (color[i] == c) total[dpt[i]]++; vector<int> cnt(n + 1), sz(n + 1); auto dfs2 = [&](auto dfs, int now, int type) -> void { sz[dpt[now]] += type; if (color[now] == c) cnt[dpt[now]] += type; for (int i : g[now]) dfs(dfs, i, type); }; for (int i = 0; i < n; i++) if (color[i] == c && top[i]) { dfs2(dfs2, i, 1); int member = 0, swp = 0; for (int j = dpt[i]; j <= n && sz[j]; j++) { //debug("depth", j, sz[j], cnt[j], total[j]); int tmp = min(total[j], sz[j]); member += tmp; swp += tmp - cnt[j]; } //debug("top", i, member, swp); if (member > ans_member) ans_member = member, ans_swp = swp; else if (member == ans_member && swp < ans_swp) ans_swp = swp; dfs2(dfs2, i, -1); } }; for (int i = 0; i < K; i++) if (SZ(pos[i]) > B) solve_big(i); { vector<deque<int>> down(n); vector<int> total(n), cnt(n); vector<bool> vst(n); auto dfs3 = [&](auto dfs, int now) -> void { down[now].pb(1); for (int i : g[now]) { dfs(dfs, i); down[i].emplace_front(0); if (SZ(down[i]) > SZ(down[now])) down[now].swap(down[i]); for (int j = 0; j < SZ(down[i]); j++) down[now][j] += down[i][j]; } //debug("dfs3", now); //pary(iter(down[now])); if (SZ(pos[color[now]]) > B) return; for (int i : pos[color[now]]) { total[dpt[i]]++; if (isAnc(now, i)) cnt[dpt[i]]++; } int member = 0, swp = 0; for (int i : pos[color[now]]) { int d = dpt[i]; if (vst[d]) continue; vst[d] = true; if (d < dpt[now] || d >= dpt[now] + SZ(down[now])) continue; int tmp = min(total[d], down[now][d - dpt[now]]); member += tmp; swp += tmp - cnt[d]; } if (member > ans_member) ans_member = member, ans_swp = swp; else if (member == ans_member && swp < ans_swp) ans_swp = swp; for (int i : pos[color[now]]) { int d = dpt[i]; total[d] = 0; cnt[d] = 0; vst[d] = false; } }; dfs3(dfs3, 0); } cout << ans_member << " " << ans_swp << "\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...