Submission #725891

#TimeUsernameProblemLanguageResultExecution timeMemory
725891victor_gaoSplit the Attractions (IOI19_split)C++17
33 / 100
218 ms73804 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 dfs(int p,int c){ vis[p]=1; for (auto i:g[p]){ if (res[i]==c&&!vis[i]) dfs(i,c); } } bool checker(){ int have[5]={0}; for (int i=1;i<=n;i++){ if (!vis[i]){ dfs(i,res[i]); have[res[i]]++; } } int h=(have[1]>1)+(have[2]>1)+(have[3]>1); cout<<h<<'\n'; return h<=1; } void get_tree(int p,int lp){ fa[p]=lp; dfn[p]=++t; idx[dfn[p]]=p; low[p]=pii(dfn[p],p); //cout<<"tree : "<<p-1<<" "<<lp-1<<'\n'; 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){ 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()); change.clear(); int now=sz[i]; // cout<<"check "<<i<<" -> \n"; for (auto [s,j]:all){ now-=s; change.push_back({i,j}); need_in.push_back(pii(low[j].y,idx[low[j].x])); // cout<<"OUT "<<j<<" "<<s<<'\n'; if (now>=a&&now<=n-a){ // cout<<i<<" find "<<now<<'\n'; for (auto [a,b]:change){ tre[a].erase(b); tre[b].erase(a); } 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; // cout<<mid<<" size is : "<<sz[mid]<<'\n'; if (sz[mid]>=b){ dfs2(mid,fa[mid]); for (auto [a,b]:need_in){ tre[a].insert(b); tre[b].insert(a); } 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); tre[b].insert(a); } for (auto i:tre[mid]) if (!res[i]) dfs2(i,mid); } //for (int i=1;i<=n;i++) // cout<<res[i]<<" "; //cout<<'\n'; 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(); //checker(); 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; } /* 13 17 2 2 9 1 0 2 0 3 0 4 0 5 1 6 4 7 1 8 3 9 7 10 1 11 4 12 1 6 2 9 8 6 7 8 7 4 3 */

Compilation message (stderr)

split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:164:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  164 |  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...