Submission #1290708

#TimeUsernameProblemLanguageResultExecution timeMemory
1290708julia_08Split the Attractions (IOI19_split)C++20
0 / 100
214 ms127264 KiB
#include <bits/stdc++.h> #include "split.h" using namespace std; const int MAXN = 1e5 + 10; vector<pair<int, int>> split; set<int> marc[MAXN]; int pre[MAXN], pos[MAXN], id[MAXN], sub[MAXN]; vector<int> adj[MAXN]; vector<int> ans; pair<int, int> first_split, second_split; int n, t = 0; void dfs_1(int v, int p){ sub[v] = 1; pre[v] = ++t; id[pre[v]] = v; for(auto u : adj[v]){ if(u != p){ dfs_1(u, v); sub[v] += sub[u]; } } for(auto u : adj[v]){ if(u != p){ if(n - sub[v] == split[0].first && sub[u] == split[1].first) first_split = {v, u}; } } pos[v] = t; } void dfs_2(int v, int p){ marc[sub[v]].erase(pre[v]); if(sub[v] == split[0].first && !marc[split[1].first].empty()){ int cand_l = *marc[split[1].first].begin(), cand_r = *marc[split[1].first].rbegin(); if(cand_l < pre[v]){ second_split = {v, id[cand_l]}; } else if(cand_r > pre[v]) second_split = {v, id[cand_r]}; } for(auto u : adj[v]){ if(u != p){ dfs_2(u, v); } } marc[sub[v]].insert(pre[v]); } bool is_sub(int a, int b){ return pre[b] <= pre[a] && pos[a] <= pos[b]; } bool check(){ dfs_1(0, 0); if(first_split.first != -1){ auto [v, u] = first_split; for(int i=0; i<n; i++){ if(is_sub(i, u)){ ans[i] = split[1].second; } else if(is_sub(i, v)){ ans[i] = split[2].second; } else ans[i] = split[0].second; } return true; } for(int i=0; i<n; i++) marc[sub[i]].insert(pre[i]); dfs_2(0, 0); if(second_split.first != -1){ auto [v, u] = second_split; for(int i=0; i<n; i++){ if(is_sub(i, v)){ ans[i] = split[0].second; } else if(is_sub(i, u)){ ans[i] = split[1].second; } else ans[i] = split[2].second; } return true; } return false; } vector<int> find_split(int n_, int a, int b, int c, vector<int> p, vector<int> q){ n = n_; ans.resize(n); for(int i=0; i<n; i++) ans[i] = 0; first_split = second_split = {-1, -1}; split = {{a, 1}, {b, 2}, {c, 3}}; for(int i=0; i<(n - 1); i++){ adj[p[i]].push_back(q[i]); adj[q[i]].push_back(p[i]); } sort(split.begin(), split.end()); bool ok = false; do{ ok |= check(); } while(!ok && next_permutation(split.begin(), split.end())); return ans; }
#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...