Submission #447139

#TimeUsernameProblemLanguageResultExecution timeMemory
447139marsxiang5902Split the Attractions (IOI19_split)C++14
100 / 100
211 ms25796 KiB
#include <bits/stdc++.h> using namespace std; typedef pair<int,int> pii; #define F first #define S second const int MN = 1e5+5, MM = 2e5+5; int N, M, asz, bsz; struct dsu{ int sz[MN]{}, par[MN]{}; int top(int u){ return par[u] ? par[u] = top(par[u]) : u; } bool merge(int u, int v){ u = top(u); v = top(v); if(u == v) return 0; if(sz[u] > sz[v]) swap(u, v); par[u] = v; sz[v] += sz[u]; return 1; } } dsu1, dsu2; vector<int> adjl[MN], adjl_all[MN]; namespace centroid{ int sz[MN]{}, col[MN]; void dfs1(int u, int p){ sz[u] = 1; for(int v: adjl[u]){ if(v != p){ dfs1(v, u); sz[u] += sz[v]; } } } int find_centroid(int u, int p){ for(int v: adjl[u]){ if(v != p){ if(sz[v] << 1 > N) return find_centroid(v, u); } } return u; } void dfs2(int u, int p, int c){ ++sz[c]; col[u] = c; for(int v: adjl[u]){ if(v != p){ dfs2(v, u, c); } } } } namespace stage_3{ vector<int> adjl2[MN]; bool vis[MN]{}; vector<int> explored; int tot_sz; void dfs(int u){ if(tot_sz >= asz) return; tot_sz += centroid::sz[u]; explored.push_back(u); vis[u] = 1; for(int v: adjl2[u]){ if(!vis[v]){ dfs(v); } } } } namespace get_ans{ bitset<MN> allowed{}; vector<int> *ans; int c, cnt; void dfs(int u, int p){ if(--cnt < 0){ return; } ans->at(u-1) = c; for(int v: adjl_all[u]){ if(ans->at(v-1) == 0 && allowed[centroid::col[v]]){ dfs(v, u); } } } } vector<int> find_split(int n, int a, int b, int c, vector<int> adjf, vector<int> adjs){ N = n; M = adjf.size(); pii ord[3] = {{a,1}, {b,2}, {c,3}}; sort(ord, ord+3); asz = ord[0].F; bsz = ord[1].F; for(int z: {0,1}){ vector<int> &vec = z ? adjf : adjs; for(int &v: vec){ ++v; } } for(int i = 0, u, v; i < M; i++){ u = adjf[i]; v = adjs[i]; if(dsu1.merge(u, v)){ adjl[u].push_back(v); adjl[v].push_back(u); } adjl_all[u].push_back(v); adjl_all[v].push_back(u); } centroid::dfs1(1, -1); int cent = centroid::find_centroid(1, -1); memset(centroid::sz, 0, sizeof centroid::sz); auto find_ans = [&](vector<int> as)->vector<int>{ using namespace get_ans; vector<int> ret(N); for(int v: as){ allowed.set(v); } get_ans::c = ord[0].S; cnt = asz; ans = &ret; dfs(as[0], cent); allowed.flip(); get_ans::c = ord[1].S; cnt = bsz; dfs(cent, -1); for(int &v: ret){ if(!v){ v = ord[2].S; } } return ret; }; for(int u: adjl[cent]){ centroid::dfs2(u, cent, u); if(centroid::sz[u] >= asz){ return find_ans({u}); } } for(int i = 0, u, v; i < M; i++){ u = adjf[i]; v = adjs[i]; if(u == cent || v == cent) continue; u = centroid::col[u]; v = centroid::col[v]; if(dsu2.merge(u, v)){ stage_3::adjl2[u].push_back(v); stage_3::adjl2[v].push_back(u); } } for(int u: adjl[cent]){ if(!stage_3::vis[u]){ stage_3::explored.clear(); stage_3::tot_sz = 0; stage_3::dfs(u); if(stage_3::tot_sz >= asz){ return find_ans(stage_3::explored); } } } return vector<int>(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...