Submission #1171733

#TimeUsernameProblemLanguageResultExecution timeMemory
1171733nguyenkhangninh99Team Coding (EGOI24_teamcoding)C++20
100 / 100
367 ms42816 KiB
#include <bits/stdc++.h> using namespace std; #define pp pair <int, int> #define fi first #define se second #define yes cout << "YES\n" #define no cout << "NO\n" const int N = 3e5 + 9; const int blocksz = 320; int n, k, c[N]; int h[N], sz[N]; int max_depth = 0; int in[N], out[N], timedfs = 0; int tour[N]; vector <int> adj[N]; vector <int> pos[N]; vector <int> large, small; int mark[N]; pp res = {1LL, 0LL}; pp cmp (pp A, pp B){ if (A.fi > B.fi) return A; if (A.fi < B.fi) return B; if (A.se <= B.se) return A; return B; } void dfs (int u){ tour[++timedfs] = u; in[u] = timedfs; max_depth = max (max_depth, h[u]); for (int v : adj[u]){ h[v] = h[u] + 1; dfs (v); } out[u] = timedfs; } int cur_color; int cnt_color[N]; int num[N]; int cnt[N]; void dfs_color (int u){ if (c[u] == cur_color){ cnt_color[h[u]]++; cnt[u]++; } for (int v : adj[u]){ dfs_color (v); cnt[u] += cnt[v]; } } int mp[N]; pp temp_ans; void dfs4 (int u){ if (mp[h[u]] < cnt_color[h[u]]) temp_ans.fi++; mp[h[u]]++; for (int v : adj[u]) dfs4 (v); } void dfs3 (int u){ if (c[u] == cur_color){ temp_ans.fi = 0; dfs4 (u); temp_ans.se = cnt[u] - temp_ans.fi; temp_ans.se = -temp_ans.se; res = cmp (res, temp_ans); for (int i = h[u]; i <= max_depth; i++) mp[i] = 0; return; } for (int v : adj[u]) dfs3 (v); } void solve_large (int color){ cur_color = color; memset (cnt, 0, sizeof (cnt)); memset (cnt_color, 0, sizeof (cnt_color)); dfs_color (1); dfs3 (1); } vector <int> L[N]; void dfs_merge (int u){ if (adj[u].size () == 0){ pos[u].push_back (1); return; } for (int v : adj[u]){ dfs_merge (v); if (pos[v].size () > pos[u].size ()) swap (pos[u], pos[v]); for (int z = 0; z < pos[v].size (); z++){ if (z >= pos[u].size ()) pos[u].push_back (0); pos[u][z] += pos[v][z]; } pos[v].clear (); } pos[u].insert (pos[u].begin (), 1); temp_ans.fi = temp_ans.se = 0; for (int i = 0; i < L[c[u]].size (); i++){ int x = L[c[u]][i]; if (h[x] < h[u]) continue; int cnt_node = 1; int in_subtree = 0; int j = i + 1; if (in[u] <= in[x] && in[x] <= out[u]) in_subtree = 1; while (j < L[c[u]].size () && h[L[c[u]][j]] == h[x]){ cnt_node++; int y = L[c[u]][j]; if (in[u] <= in[y] && in[y] <= out[u]) in_subtree++; j++; if (j >= L[c[u]].size ()) break; } if (h[x] - h[u] < pos[u].size () && h[x] - h[u] >= 0){ temp_ans.fi += min (cnt_node, pos[u][h[x] - h[u]]); temp_ans.se += min (cnt_node, pos[u][h[x] - h[u]]) - in_subtree; } i = j - 1; } res = cmp (res, temp_ans); } bool cmp_depth (int u, int v){ return h[u] < h[v]; } void solve_small (){ for (int i = 1; i <= n; i++){ if (mark[c[i]] == 0) continue; L[c[i]].push_back (i); } for (int i = 0; i < k; i++) if (L[i].size ()) sort (L[i].begin (), L[i].end (), cmp_depth); dfs_merge (1); } signed main (){ ios_base::sync_with_stdio (false); cin.tie(0); cout.tie(0); cin >> n >> k; for (int i = 1; i <= n; i++){ cin >> c[i]; sz[c[i]]++; } for (int i = 0; i < k; i++){ if (sz[i] >= blocksz) large.push_back (i); else if (sz[i]){ small.push_back (i); mark[i]++; } } for (int i = 2, p; i <= n; i++){ cin >> p; p++; adj[p].push_back (i); } dfs (1); for (int i : large) solve_large (i); solve_small (); cout << res.fi << ' ' << res.se; }
#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...