제출 #296824

#제출 시각아이디문제언어결과실행 시간메모리
296824rqiSplit the Attractions (IOI19_split)C++14
0 / 100
130 ms18152 KiB
#include "split.h" #include <bits/stdc++.h> using namespace std; typedef vector<int> vi; typedef pair<int, int> pi; typedef vector<pi> vpi; #define pb push_back #define sz(x) (int)(x).size() #define mp make_pair #define f first #define s second #define all(x) begin(x), end(x) const int mx = 100005; struct DSU{ vi e; void init(int n){ e = vi(n, -1); } int get(int a){ if(e[a] < 0) return a; e[a] = get(e[a]); return e[a]; } int getSz(int a){ return -e[get(a)]; } bool sameSet(int a, int b){ return get(a) == get(b); } bool unite(int a, int b){ a = get(a); b = get(b); if(a == b) return 0; if(-e[a] < -e[b]) swap(a, b); //a now has bigger size e[a]+=e[b]; e[b] = a; return 1; } }; int n, a, b, c; vi L; vi res; vi tadj[mx]; //tree edges DSU dsu; vpi extr; int sub[mx]; void genSub(int node, int prv = -1){ sub[node] = 1; for(auto u: tadj[node]){ if(u == prv) continue; genSub(u, node); sub[node]+=sub[u]; } } int getCen(int node, int prv = -1){ for(auto u: tadj[node]){ if(u == prv) continue; if(sub[u] >= n-sub[u]) return getCen(u, node); } return node; } int und[mx]; //underneath a node under cen vi rund[mx]; vi sadj[mx]; //adjacent things in cnt graph void genUnd(int node, int val, int prv = -1){ und[node] = val; rund[val].pb(node); for(auto u: tadj[node]){ if(u == prv) continue; genUnd(u, val, node); } } bool good[mx]; int curw; bool inSet[mx]; void getW(int node){ if(!good[node]) return; if(inSet[node]) return; if(curw >= L[0]) return; inSet[node] = 1; curw+=sub[node]; for(auto u: sadj[node]){ getW(u); } } int tcount = 0; void assign2(int node){ if(tcount >= L[1]) return; if(res[node] != 0) return; res[node] = 2; tcount++; for(auto u: tadj[node]){ assign2(u); } } void adjustRes(){ vi to(4, 0); vi vals(4, 0); for(auto u: res) vals[u]++; vpi cnt1, cnt2; cnt1.pb(mp(a, 1)); cnt1.pb(mp(b, 2)); cnt1.pb(mp(c, 3)); cnt2.pb(mp(vals[1], 1)); cnt2.pb(mp(vals[2], 2)); cnt2.pb(mp(vals[3], 3)); sort(all(cnt1)); sort(all(cnt2)); for(int i = 0; i < 3; i++){ to[cnt2[i].s] = cnt1[i].s; } for(auto &u: res) u = to[u]; } vi find_split(int _n, int _a, int _b, int _c, vi p, vi q) { n = _n, a = _a, b = _b, c = _c; L = vi{a, b, c}; sort(all(L)); res = vi(n, 0); dsu.init(n); for(int i = 0; i < sz(p); i++){ if(dsu.unite(p[i], q[i])){ tadj[p[i]].pb(q[i]); tadj[q[i]].pb(p[i]); } else{ extr.pb(mp(p[i], q[i])); } } genSub(0); int cen = getCen(0); for(auto u: tadj[cen]){ genUnd(u, u, cen); //cout << u << " " << u << "\n"; } //cout << cen << "\n"; genSub(cen); dsu.init(n); for(auto u: tadj[cen]){ dsu.e[u] = -sub[u]; //cout << u << " " << dsu.e[u] << "\n"; } for(auto u: extr){ if(u.f == cen || u.s == cen) continue; dsu.unite(und[u.f], und[u.s]); sadj[und[u.f]].pb(und[u.s]); sadj[und[u.s]].pb(und[u.f]); //cout << und[u.f] << " " << und[u.s] << "\n"; } for(auto u: tadj[cen]){ if(dsu.getSz(u) >= L[0]){ for(auto x: tadj[cen]){ if(dsu.sameSet(u, x)){ good[x] = 1; } } curw = 0; getW(u); for(auto x: tadj[cen]){ if(inSet[x]){ for(auto y: rund[x]){ //cout << y << "\n"; res[y] = 1; } } } assign2(cen); for(auto &u: res) if(u == 0) u = 3; adjustRes(); return res; } } return res; }
#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...