Submission #386472

#TimeUsernameProblemLanguageResultExecution timeMemory
386472VROOM_VARUNMeetings 2 (JOI21_meetings2)C++14
100 / 100
1816 ms42632 KiB
/* ID: varunra2 LANG: C++ TASK: meetings2 */ // run centroid decomposition // reroot // ???? // profit #include <bits/stdc++.h> using namespace std; #ifdef DEBUG #include "lib/debug.h" #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) #define debug_arr(...) \ cerr << "[" << #__VA_ARGS__ << "]:", debug_arr(__VA_ARGS__) #pragma GCC diagnostic ignored "-Wsign-compare" //#pragma GCC diagnostic ignored "-Wunused-parameter" //#pragma GCC diagnostic ignored "-Wunused-variable" #else #define debug(...) 42 #endif #define EPS 1e-9 #define IN(A, B, C) assert(B <= A && A <= C) #define INF (int)1e9 #define MEM(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define MP make_pair #define PB push_back #define all(cont) cont.begin(), cont.end() #define rall(cont) cont.end(), cont.begin() #define x first #define y second const double PI = acos(-1.0); typedef long long ll; typedef long double ld; typedef pair<int, int> PII; typedef map<int, int> MPII; typedef multiset<int> MSETI; typedef set<int> SETI; typedef set<string> SETS; typedef vector<int> VI; typedef vector<PII> VII; typedef vector<VI> VVI; typedef vector<string> VS; #define rep(i, a, b) for (int i = a; i < (b); ++i) #define trav(a, x) for (auto& a : x) #define sz(x) (int)(x).size() typedef pair<int, int> pii; typedef vector<int> vi; #pragma GCC diagnostic ignored "-Wsign-compare" // util functions int n; VVI adj; VI sub; VI out; VI treel; VI treer; vector<bool> rem; VI s; VI cent; VI ret; VI par; VI parent; VI dist; int tme = 0; void init() { adj.resize(n); sub.resize(n); out.resize(n); treel.resize(n); treer.resize(n); rem.assign(n, false); s.assign(n, 0); cent.resize(n); ret.assign(n + 1, 0); par.resize(n); parent.resize(n); dist.resize(n); } void dfsinit(int u, int v) { parent[u] = v; treel[u] = tme++; sub[u] = 1; for (auto& x : adj[u]) { if (x == v) continue; dfsinit(x, u); sub[u] += sub[x]; } out[u] = (n + 1) - sub[u]; treer[u] = tme++; } int dfs(int n, int p = -1) { s[n] = 1; trav(x, adj[n]) { if (x != p and !rem[x]) { s[n] += dfs(x, n); } } return s[n]; } int get_centroid(int n, int ms, int p = -1) { for (auto& x : adj[n]) { if (x != p and !rem[x]) { if (s[x] * 2 > ms) { return get_centroid(x, ms, n); } } } return n; } void centroid(int n = 0, int lvl = 0, int parr = -1) { int C = get_centroid(n, dfs(n)); par[C] = parr; cent[C] = lvl++; rem[C] = true; for (auto& x : adj[C]) { if (!rem[x]) centroid(x, lvl, C); } } bool isAnc(int u, int v) { if (u == -1) return true; if (v == -1) return false; if (treel[u] <= treel[v] and treer[u] >= treer[v]) return true; return false; } int calc(int u, int v) { if (isAnc(u, v)) return (n - sub[v]); return sub[u]; } void dfsdist(int u, int v, int part, int centfrom, VVI& evnts, int& cnt) { // we calculate distance here if (cent[u] <= cent[centfrom]) return; int val = min(calc(u, v), calc(centfrom, part)); cnt++; dist[u] = dist[v] + 1; ret[2 * val] = max(ret[2 * val], dist[u] + 1); evnts.PB({calc(u, v), dist[u], part}); for (auto& x : adj[u]) { if (x == v) continue; dfsdist(x, u, part, centfrom, evnts, cnt); } } void upd(PII nw, pair<PII, PII>& bst) { if (nw.y == bst.x.y) { bst.x = max(bst.x, nw); } else if (nw.y == bst.y.y) { bst.y = max(bst.y, nw); if (bst.x < bst.y) swap(bst.x, bst.y); } else { if (nw > bst.x) { bst.y = bst.x; bst.x = nw; } else { if (nw > bst.y) { bst.y = nw; } } } } void solve(int u) { // solve it for node u // choose a path that HAS to go through u // first let us calculate the sub stuff lmfao VVI evnts; dist[u] = 0; int cnt = 1; for (auto& x : adj[u]) { dfsdist(x, u, x, u, evnts, cnt); } // for (int i = 1; i <= cnt / 2; i++) { // evnts.PB({i, -1}); // } // MPII there; // for(auto& x: evnts) { // there[x[0]]++; // } // trav(x, there) { // evnts.PB({x.x, -1}); // } sort(all(evnts), greater<VI>()); pair<PII, PII> bst = MP(MP(0, -1), MP(0, -2)); for (auto& x : evnts) { // if (sz(x) == 3) { // new vertex to add upd(MP(x[1], x[2]), bst); // } else { if (bst.x.x == 0 or bst.y.x == 0) continue; int val = bst.x.x + bst.y.x + 1; ret[2 * x[0]] = max(ret[2 * x[0]], val); // debug(val, 2 * x[0], bst, u); } // } } int main() { // #ifndef ONLINE_JUDGE // freopen("meetings2.in", "r", stdin); // freopen("meetings2.out", "w", stdout); // #endif cin.sync_with_stdio(0); cin.tie(0); cin >> n; init(); for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; u--, v--; adj[u].PB(v); adj[v].PB(u); } dfsinit(0, -1); centroid(); for (int i = 0; i < n; i++) { solve(i); } int mx = 1; for (int i = n / 2; i >= 1; i--) { ret[2 * i] = max(ret[2 * i], mx); mx = ret[2 * i]; } for (int i = 1; i <= n; i++) { if (i & 1) cout << 1 << '\n'; else cout << ret[i] << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...