제출 #1088375

#제출 시각아이디문제언어결과실행 시간메모리
1088375steveonalexSplit the Attractions (IOI19_split)C++17
100 / 100
92 ms30844 KiB
#include <bits/stdc++.h> #include "split.h" using namespace std; typedef long long ll; typedef unsigned long long ull; #define MASK(i) (1LL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() #define block_of_code if(true) ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll gcd(ll a, ll b){return __gcd(a, b);} ll lcm(ll a, ll b){return a / gcd(a, b) * b;} ll LASTBIT(ll mask){return (mask) & (-mask);} int pop_cnt(ll mask){return __builtin_popcountll(mask);} int ctz(ull mask){return __builtin_ctzll(mask);} int logOf(ull mask){return 63 - __builtin_clzll(mask);} mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);} double rngesus_d(double l, double r){ double cur = rngesus(0, MASK(60) - 1); cur /= MASK(60) - 1; return l + cur * (r - l); } template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b) {a = b; return true;} return false; } template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b) {a = b; return true;} return false; } template <class T> void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){ for(auto item: container) out << item << separator; out << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } const int N = 2e5 + 69; namespace Sub5{ int n, m; array<int, 4> cc_size; vector<int> graph[N], tree[N]; int sz[N], parent[N], h[N], up[N]; int dfs_cnt = 0; void construct_dfs_tree(int u, int p){ sz[u] = 1; up[u] = h[u] = h[p] + 1; for(int v: graph[u]) { if (v == p) { p = -1; continue; } if (h[v] == 0){ construct_dfs_tree(v, u); tree[u].push_back(v); sz[u] += sz[v]; } else{ minimize(up[u], h[v]); } } } void dfs(int u, array<int, 3> &perm, vector<int> &good_vertices){ int cnt = 0; for(int v: tree[u]) if (sz[v] >= cc_size[perm[0]]){ cnt++; dfs(v, perm, good_vertices); } if (cnt == 0) good_vertices.push_back(u); } void find_legal(int u, int good_height, int a, int &p1, int &p2, vector<int> &balls){ if (up[u] < good_height && p1 - sz[u] >= a){ p1 -= sz[u]; p2 += sz[u]; balls.push_back(u); return; } for(int v: tree[u]) find_legal(v, good_height, a, p1, p2, balls); } void paint_subtree(int u, int c, vector<int> &ans){ ans[u] = c; for(int v: tree[u]){ paint_subtree(v, c, ans); } } void flip_cc(int u, int &cnt, vector<int> &ans){ if (cnt == 0) return; cnt--; ans[u] *= -1; for(int v: graph[u]) if (ans[v] < 0 && ans[v] == -ans[u]){ flip_cc(v, cnt, ans); } } vector<int> _try(array<int, 3> perm){ vector<int> ans(n, 0); vector<int> good_vertices; dfs(0, perm, good_vertices); // cout << "Perm: "; printArr(perm); for(int u: good_vertices) if (u != 0) { int p1 = sz[u], p2 = n - sz[u]; vector<int> balls; find_legal(u, h[u], cc_size[perm[0]], p1, p2, balls); if (p2 >= cc_size[perm[1]]){ paint_subtree(0, -perm[1], ans); paint_subtree(u, -perm[0], ans); for(int v: balls) paint_subtree(v, -perm[1], ans); int p1 = cc_size[perm[0]], p2 = cc_size[perm[1]]; flip_cc(0, p2, ans); flip_cc(u, p1, ans); for(int i = 0; i < n; ++i) if (ans[i] < 0) ans[i] = perm[2]; break; } } return ans; } vector<int> solve(int _n, int a, int b, int c, vector<int> p, vector<int> q){ cc_size = {{0, a, b, c}}; n = _n, m = p.size(); for(int i = 0; i<m; ++i){ int u = p[i], v = q[i]; graph[u].push_back(v); graph[v].push_back(u); } construct_dfs_tree(0, n); vector<int> ans(n, 0); array<int, 3> perm = {{1, 2, 3}}; sort(ALL(perm), [](int x, int y){ return cc_size[x] < cc_size[y]; }); for(int i = 0; i<=1; ++i){ if (maximize(ans, _try(perm))) break; swap(perm[0], perm[1]); } return ans; } } vector<int> find_split(int n, int a, int b, int c, vector<int> p, vector<int> q) { return Sub5::solve(n, a, b, c, p, q); } // int main(void){ // ios::sync_with_stdio(0);cin.tie(0); cout.tie(0); // clock_t start = clock(); // int n, m; cin >> n >> m; // int a, b, c; cin >> a >> b >> c; // vector<int> p(m), q(m); // for(int i= 0; i<m; ++i) cin >> p[i] >> q[i]; // vector<int> ans = find_split(n, a, b, c, p, q); // printArr(ans); // cerr << "Time elapsed: " << clock() - start << " ms\n"; // return 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...