Submission #725825

#TimeUsernameProblemLanguageResultExecution timeMemory
725825victor_gaoSplit the Attractions (IOI19_split)C++17
40 / 100
163 ms36644 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; set<int>tre[N]; int sz[N],a,b,c,mx[N],deg[N],fa[N],cnt[N],n,dfn[N],t=0,now1,now2; void get_tree(int p,int lp){ fa[p]=lp; dfn[p]=++t; //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); cnt[p]+=cnt[i]; } else if (i!=lp&&dfn[i]<dfn[p]){ cnt[p]++; cnt[i]--; } } } 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]&&cnt[j]) all.push_back({sz[j],j}); } sort(all.begin(),all.end()); change.clear(); int now=sz[i]; for (auto [s,j]:all){ now-=s; change.push_back({i,j}); 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]:change){ 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]:change){ 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(); 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; } /* 10 10 4 3 3 0 1 1 2 1 4 1 5 4 6 0 7 3 8 2 9 0 3 1 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:139:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  139 |  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...