제출 #679820

#제출 시각아이디문제언어결과실행 시간메모리
679820cadmiumskySplit the Attractions (IOI19_split)C++14
100 / 100
164 ms26648 KiB
#include <bits/stdc++.h> #define all(x) (x).begin(),(x).end() using namespace std; using ll = long long; #define sz(x) (int)(x).size() using pii = pair<int,int>; using tii = tuple<int,int,int>; const int nmax = 1e5 + 5; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int n; vector<int> leg[nmax]; struct Tree { vector<int> g[nmax]; int root; void clear() { for(int i = 0; i < n; i++) g[i].clear(); return; } void addedge(int a, int b) { g[a].emplace_back(b); g[b].emplace_back(a); } vector<int> togive; int mxarea[nmax], area[nmax], p[nmax]; void down(int node, int f) { p[node] = f; for(auto x : g[node]) { if(x == f) continue; down(x, node); area[node] += area[x]; mxarea[node] = max(mxarea[node], area[x]); } area[node]++; } void init() { togive.resize(n, 0); down(root, root); } void fillgreedy(int node, int f, int& a) { if(a == 0) return; sort(all(g[node]), [&](int x, int b) { return area[x] < area[b] || (area[x] > a && area[b] > a && mxarea[x] < mxarea[b]); }); togive[node] = 1; a--; for(auto x : g[node]) { if(x == f) continue; fillgreedy(x, node, a); if(a == 0) return; } } vector<int> getbydown(int a) { std::fill(all(togive), 0); int best = root; for(int i = 0; i < n; i++) if(area[i] >= a && area[best] > area[i]) best = i; fillgreedy(best, p[best], a); return togive; } vector<int> getbyroot(int a) { std::fill(all(togive), 0); fillgreedy(root, root, a); return togive; } int flag = 2; int fill(int node, vector<int>& occ, int& b) { if(b == 0) return 0; if(occ[node] != 0) return 0; occ[node] = flag; int sum = 1; b--; for(auto x : leg[node]) sum += fill(x, occ, b); return sum; } void fill(vector<int> &occ, int b) { for(int i = 0; i < n; i++) { if(occ[i] == 0) { flag++; int tmp = b; fill(i, occ, b); if(b == 0) { //for(auto x : occ) //cerr << x << ' '; //cerr << '\n'; //cerr << flag << '\n'; for(auto &x : occ) { if(x == 1) continue; if(x == flag) x = 2; else x = 3; } return; } b = tmp; } } occ.back() = -1; return; } } tree; int occ[nmax]; void dfs(int node) { if(occ[node] == 1) return; occ[node] = 1; for(auto x : leg[node]) { if(occ[x] == 0) { tree.addedge(node, x); dfs(x); } } return; } void constr_tree(vector<pii>& edg, int rt) { tree.clear(); for(int i = 0; i < n; i++) leg[i].clear(); for(auto [a, b] : edg) leg[a].emplace_back(b), leg[b].emplace_back(a); tree.root = rt; dfs(rt); tree.init(); } int rnd(int x) {return rng() % x;} vector<int> sol; void verif(int node, int col) { sol[node] = -1; for(auto x : leg[node]) { if(sol[x] == col) { verif(x, col); } } } std::vector<int> find_split(int N, int a, int b, int c, std::vector<int> p, std::vector<int> q) { n = N; int hsh[3] = {0, 1, 2}; { // renumerotare if(a > b) swap(hsh[0], hsh[1]), swap(a, b); if(b > c) swap(hsh[1], hsh[2]), swap(b, c); if(a > b) swap(hsh[0], hsh[1]), swap(a, b); } vector<pii> edg; for(int i = 0; i < sz(p); i++) edg.emplace_back(p[i], q[i]); vector<int> var(n, -1); int counted = 0; int sus = 0; do { constr_tree(edg, sus); vector<int> var1 = tree.getbydown(a), var2 = tree.getbyroot(a); tree.fill(var1, b); tree.fill(var2, b); if(var1.back() == -1) swap(var1, var2); var = move(var1); counted++; random_shuffle(all(edg), rnd); //sus = rnd(n); } while(var.back() == -1 && counted < 1); if(var.back() == -1) { fill(all(var), 0); return var; } sol = var; int cnts = 0; for(int i = 0; i < n; i++) { if(sol[i] == 1) cnts++, verif(i, 1); if(sol[i] == 2) cnts++, verif(i, 2); } //cerr << cnts << '\n'; assert(cnts == 2); int cnt[3] = {0, 0, 0}; for(auto &x : var) { x--; x = hsh[x]; x++; } return var; }

컴파일 시 표준 에러 (stderr) 메시지

split.cpp: In function 'void constr_tree(std::vector<std::pair<int, int> >&, int)':
split.cpp:130:12: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  130 |   for(auto [a, b] : edg)
      |            ^
split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:202:7: warning: unused variable 'cnt' [-Wunused-variable]
  202 |   int cnt[3] = {0, 0, 0};
      |       ^~~
#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...