Submission #725912

#TimeUsernameProblemLanguageResultExecution timeMemory
725912victor_gaoSplit the Attractions (IOI19_split)C++17
100 / 100
247 ms37448 KiB
#pragma GCC optimize("Ofast,unroll-loops") #include "split.h" #include <bits/stdc++.h> #define pii pair<int,int> #define x first #define y second #define N 100015 using namespace std; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); vector<int>g[N],leaf1,leaf2,res; vector<pii>change,need_in; set<int>tre[N]; int sz[N],n,a,b,c,mx[N],deg[N],fa[N]; int now1,now2,t=0,dfn[N],idx[2*N]; pii low[N]; bool vis[N]; void get_tree(int p,int lp){ fa[p]=lp; dfn[p]=++t; idx[dfn[p]]=p; low[p]=pii(dfn[p],p); for (auto i:g[p]){ if (!dfn[i]){ tre[i].insert(p); tre[p].insert(i); get_tree(i,p); low[p]=min(low[p],low[i]); } else if (i!=lp&&dfn[i]<dfn[p]) low[p]=min(low[p],pii(dfn[i],p)); } } void count_size(int p,int lp){ sz[p]=1; deg[p]=tre[p].size(); mx[p]=0; for (auto i:tre[p]){ if (i!=lp){ count_size(i,p); mx[p]=max(mx[p],sz[i]); sz[p]+=sz[i]; } } } void dfs1(int p,int lp){ res[p]=1; now1++; if (tre[p].size()==1) leaf1.push_back(p); for (auto i:tre[p]) if (i!=lp&&!res[i]) dfs1(i,p); } void dfs2(int p,int lp){ res[p]=2; now2++; if (tre[p].size()==1) leaf2.push_back(p); for (auto i:tre[p]) if (i!=lp&&!res[i]) dfs2(i,p); } bool check(int i){ change.clear(); need_in.clear(); if (sz[i]>=a&&sz[i]<=n-a) return 1; vector<pii>all; for (auto j:tre[i]){ if (j!=fa[i]&&low[j].x<dfn[i]) all.push_back({sz[j],j}); } sort(all.begin(),all.end()); int now=sz[i]; for (auto [s,j]:all){ now-=s; change.push_back({i,j}); need_in.push_back(pii(low[j].y,idx[low[j].x])); if (now>=a&&now<=n-a){ for (auto [a,b]:change){ tre[a].erase(b); deg[a]--; tre[b].erase(a); deg[b]--; } sz[i]=now; return 1; } } return 0; } void solve(){ count_size(1,0); int mid=0; for (int i=1;i<=n;i++){ if (check(i)){ mid=i; break; } } if (mid==0) return; if (sz[mid]>=b){ dfs2(mid,fa[mid]); for (auto [a,b]:need_in){ tre[a].insert(b); deg[a]++; tre[b].insert(a); deg[b]++; } for (auto i:tre[mid]) if (!res[i]) dfs1(i,mid); } else { dfs1(mid,fa[mid]); for (auto [a,b]:need_in){ tre[a].insert(b); deg[a]++; tre[b].insert(a); deg[b]++; } for (auto i:tre[mid]) if (!res[i]) dfs2(i,mid); } while (now1>a){ int out=leaf1.back(); leaf1.pop_back(); res[out]=3; now1--; for (auto i:tre[out]){ deg[i]--; if (deg[i]==1) leaf1.push_back(i); } } while (now2>b){ int out=leaf2.back(); leaf2.pop_back(); res[out]=3; now2--; for (auto i:tre[out]){ deg[i]--; if (deg[i]==1) leaf2.push_back(i); } } } vector<int> find_split(int _n, int A, int B, int C, vector<int> p, vector<int> q) { n=_n; vector<pii>s={{A,1},{B,2},{C,3}}; sort(s.begin(),s.end()); a=s[0].x; b=s[1].x; c=s[2].x; for (int i=0;i<p.size();i++){ g[p[i]+1].push_back(q[i]+1); g[q[i]+1].push_back(p[i]+1); } res.resize(n+1); get_tree(1,0); solve(); vector<int>ans; ans.resize(n,0); if (res[1]==0) return ans; for (int i=1;i<=n;i++) ans[i-1]=(s[res[i]-1].y); return ans; }

Compilation message (stderr)

split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:137:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  137 |  for (int i=0;i<p.size();i++){
      |               ~^~~~~~~~~
#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...