Submission #1030377

#TimeUsernameProblemLanguageResultExecution timeMemory
1030377KanonBeech Tree (IOI23_beechtree)C++17
100 / 100
107 ms38484 KiB
#include <bits/stdc++.h> using namespace std; vector<int> beechtree(int n, int m, vector<int> P, vector<int> C) { vector<vector<int>> g(n); for (int i = 1; i < n; i++) g[P[i]].push_back(i); for (int i = 0; i < n; i++) sort(g[i].begin(), g[i].end(), [&](int u, int v){ return C[u] < C[v]; }); vector<int> sub(n); for (int i = n - 1; i >= 0; i--) { sub[i] = 1; for (int j : g[i]) sub[i] += sub[j]; } vector<int> heavy(n); for (int i = 0; i < n; i++) { heavy[i] = -1; for (int j : g[i]) { if (heavy[i] == -1 || sub[heavy[i]] < sub[j]) heavy[i] = j; } } vector<int> ret(n, -1); vector<set<pair<int, int>>> res(n); for (int v = n - 1; v >= 0; v--) { if (heavy[v] == -1) { ret[v] = 1; res[v].insert({sub[v], v}); continue; } for (int i : g[v]) { assert(ret[i] != -1); if (ret[i] == 0) { ret[v] = 0; break; } } for (int i = 0; i < (int) g[v].size() - 1; i++) { if (C[g[v][i]] == C[g[v][i + 1]]) { ret[v] = 0; break; } } if (ret[v] == 0) continue; auto is_cover = [&](int big, int small) { if (g[big].size() < g[small].size()) return false; int id = 0; for (int i = 0; i < (int) g[small].size(); i++) { while (id < (int) g[big].size() && C[g[big][id]] != C[g[small][i]]) id++; if (id == (int) g[big].size()) return false; int B = g[big][id], S = g[small][i]; if (sub[B] < sub[S]) return false; } return true; }; swap(res[v], res[heavy[v]]); for (int u : g[v]) { if (u == heavy[v]) continue; vector<int> order; for (auto [_, nd] : res[u]) order.push_back(nd); for (int nd : order) { auto R = res[v].lower_bound(make_pair(sub[nd], -1)); if (R == res[v].end() || R->first > sub[nd]) { if (R != res[v].end()) { if (!is_cover(R->second, nd)) { ret[v] = 0; break; } } if (R != res[v].begin()) { auto L = prev(R); if (!is_cover(nd, L->second)) { ret[v] = 0; break; } } res[v].insert(make_pair(sub[nd], nd)); } else { assert(R->first == sub[nd]); if (!is_cover(R->second, nd) || !is_cover(nd, R->second)) { ret[v] = 0; break; } } } if (ret[v] == 0) break; } if (ret[v] != 0 && res[v].size()) { int nxt = prev(res[v].end())->second; if (!is_cover(v, nxt)) { ret[v] = 0; } } if (ret[v] == 0) { res[v].clear(); } else { ret[v] = 1; res[v].insert(make_pair(sub[v], v)); } } return ret; }
#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...
#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...