Submission #386556

#TimeUsernameProblemLanguageResultExecution timeMemory
386556PurpleCrayonMeetings 2 (JOI21_meetings2)C++17
100 / 100
695 ms44996 KiB
#include <bits/stdc++.h> using namespace std; #define ar array #define sz(v) int(v.size()) const int MAXN = 2e5+10, MAXL = 18, INF = 1e9+10; int n, depth[MAXN], anc[MAXN][MAXL], st[MAXN], en[MAXN], tt=0; vector<int> adj[MAXN]; //start lca void init_lca(int c=0, int p=-1, int d=0){ depth[c]=d, anc[c][0]=p; st[c] = tt++; for (int i=1; i < MAXL; i++) anc[c][i] = (anc[c][i-1]==-1?-1:anc[anc[c][i-1]][i-1]); for (auto nxt : adj[c]) if (nxt != p) init_lca(nxt, c, d+1); en[c] = tt-1; } int jmp(int a, int h){ for (int i = 0; i < MAXL; i++) if ((h>>i)&1) a = anc[a][i]; return a; } int lca(int a, int b){ if (depth[a] < depth[b]) swap(a, b); a = jmp(a, depth[a]-depth[b]); if (a==b) return a; for (int i = MAXL-1; i >= 0; i--){ if (anc[a][i] != anc[b][i]) a = anc[a][i], b = anc[b][i]; } assert(anc[a][0]==anc[b][0]); return anc[a][0]; } int dist(int a, int b){ return depth[a]+depth[b]-2*depth[lca(a, b)]; } //end lca int sub[MAXN], ans[MAXN]; int dfs1(int c=0, int p=-1){ sub[c] = 1; for (auto nxt : adj[c]) if (nxt != p) sub[c] += dfs1(nxt, c); return sub[c]; } struct pt_upd { int n, t[4*MAXN]; void init(int _n){ n=_n; memset(t, -1, sizeof(t)); } void upd(int v, int tl, int tr, int pos, int nv){ if (pos < tl || pos > tr) return; if (tl == tr) { t[v] = nv; return; } int tm=(tl+tr)/2; upd(2*v, tl, tm, pos, nv), upd(2*v+1, tm+1, tr, pos, nv); t[v] = max(t[2*v], t[2*v+1]); } void upd(int pos, int nv){ upd(1, 0, n-1, pos, nv); } int qry(int v, int tl, int tr, int l, int r) { if (r < tl || l > tr) return -1; if (l <= tl && tr <= r) return t[v]; int tm=(tl+tr)/2; return max(qry(2*v, tl, tm, l, r), qry(2*v+1, tm+1, tr, l, r)); } int qry(int l, int r){ return qry(1, 0, n-1, l, r); } } seg1; struct rng_upd { int n, t[4*MAXN]; void init(int _n){ n=_n; fill(t, t+4*n, INF); } void upd(int v, int tl, int tr, int l, int r, int val){ if (r < tl || l > tr) return; if (l <= tl && tr <= r) { t[v] = min(t[v], val); return; } int tm=(tl+tr)/2; upd(2*v, tl, tm, l, r, val), upd(2*v+1, tm+1, tr, l, r, val); } void upd(int l, int r, int nv){ upd(1, 0, n-1, l, r, nv); } int qry(int v, int tl, int tr, int pos) { if (tl == tr) return t[v]; int ans=t[v], tm = (tl+tr)/2; if (pos <= tm) ans = min(ans, qry(2*v, tl, tm, pos)); else ans = min(ans, qry(2*v+1, tm+1, tr, pos)); return ans; } int qry(int pos){ return qry(1, 0, n-1, pos); } } seg2; int main(){ ios::sync_with_stdio(false); cin.tie(0); cin >> n; for (int i = 0; i < n-1; i++){ int a, b; cin >> a >> b, --a, --b; adj[a].push_back(b), adj[b].push_back(a); } init_lca(); dfs1(); vector<int> p1(n); iota(p1.begin(), p1.end(), 0); sort(p1.begin(), p1.end(), [&](int i, int j){ return sub[i] < sub[j]; }); vector<bool> is_lf(n); ar<int, 2> diam{-1, -1}; vector<int> p2(n-1); iota(p2.begin(), p2.end(), 1); sort(p2.begin(), p2.end(), [&](int i, int j){ return n-sub[i] < n-sub[j]; }); seg1.init(n); seg2.init(n); int up_len = -1; vector<int> lf; int ptr1=n-1, ptr2=n-2; for (int i = n; i >= 1; i--) { if (i&1){ ans[i] = 1; continue; } int v=i/2; while (ptr1>=0&&sub[p1[ptr1]]>=v) { int j = p1[ptr1]; //cerr << "add down " << j << " for answer " << i << endl; if (sz(lf)<=2) { if (j){ if (is_lf[anc[j][0]]) { lf.erase(find(lf.begin(), lf.end(), anc[j][0])); is_lf[anc[j][0]] = 0; } is_lf[j] = 1; lf.push_back(j); } } if (sz(lf) == 2) { diam = {lf[0], lf[1]}; } else if (sz(lf) > 2) { int d1=dist(diam[0], diam[1]), d2=dist(diam[0], j), d3=dist(diam[1], j); if (d1 == max({d1, d2, d3})) { } else if (d2 == max({d1, d2, d3})) { diam = {diam[0], j}; } else if (d3 == max({d1, d2, d3})) { diam = {diam[1], j}; } else assert(false); } seg1.upd(st[j], depth[j]); up_len = max(up_len, depth[j]-seg2.qry(st[j])); ptr1--; } while (ptr2>=0&&n-sub[p2[ptr2]]>=v) { int j = p2[ptr2]; //cerr << "add up " << j << " for answer " << i << endl; up_len = max(up_len, seg1.qry(st[j], en[j])-(depth[j]-1)); seg2.upd(st[j], en[j], (depth[j]-1)); ptr2--; } //cerr << "diam: " << i << ' ' << diam[0] << ' ' << diam[1] << ' ' << sz(lf) << endl; ans[i] = 1+up_len; if (sz(lf) >= 2) ans[i] = max(ans[i], 1+dist(diam[0], diam[1])); ans[i] = max(ans[i], 1); } for (int i = 1; i <= n; i++) cout << ans[i] << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...