제출 #1286238

#제출 시각아이디문제언어결과실행 시간메모리
1286238denislavMeetings 2 (JOI21_meetings2)C++20
0 / 100
2 ms576 KiB
# include <iostream> # include <vector> using namespace std; template<class T> void chmax(T& x, const T& y) {x=max(x,y);} const int MAX=2e5+11,INF=1e9,LOG=20; int n; vector<int> adj[MAX]; int out[MAX]; int SZ[MAX]; int H[MAX]; int st[MAX][LOG]; void dfs_lca(int curr, int par) { SZ[curr]=1; for(int nxt: adj[curr]) { if(nxt==par) continue; H[nxt]=H[curr]+1; st[nxt][0]=curr; dfs_lca(nxt,curr); SZ[curr]+=SZ[nxt]; } } void lca_precalc() { dfs_lca(1,0); for(int j=1;j<LOG;j++) { for(int i=1;i<=n;i++) { if(H[i]-(1<<j)<0) continue; st[i][j]=st[st[i][j-1]][j-1]; } } } int lift(int u, int k) { for(int j=LOG-1;j>=0;j--) { if(k-(1<<j)>=0) { u=st[u][j]; k-=(1<<j); } } return u; } int get_lca(int u, int v) { if(H[u]<H[v]) swap(u,v); for(int j=LOG-1;j>=0;j--) { if(H[u]-(1<<j)>=H[v]) { u=st[u][j]; } } if(u==v) return u; for(int j=LOG-1;j>=0;j--) { if(H[u]-(1<<j)>=0 and st[u][j]!=st[v][j]) { u=st[u][j]; v=st[v][j]; } } return st[u][v]; } pair<int,int> sizes(int u, int v) { int lca=get_lca(u,v); if(lca!=u and lca!=v) return {SZ[u],SZ[v]}; bool Swap=0; if(u!=lca) { Swap=1; swap(u,v); } pair<int,int> ans; ans={n-SZ[lift(v,H[v]-H[u]-1)],SZ[v]}; if(Swap) swap(ans.first,ans.second); return ans; } bool banned[MAX]; int sz[MAX]; int h[MAX]; void dfs_sz(int curr, int par) { sz[curr]=1; for(int nxt: adj[curr]) { if(nxt==par or banned[nxt]) continue; h[nxt]=h[curr]+1; dfs_sz(nxt,curr); sz[curr]+=sz[nxt]; } } int get_centroid(int curr, int par, int N) { for(int nxt: adj[curr]) { if(nxt==par or banned[nxt]) continue; if(sz[nxt]*2>N) return get_centroid(nxt,curr,N); } return curr; } struct segtree { int tree[MAX*4]; void build(int v=1, int l=0, int r=n) { if(l==r) { tree[v]=-INF; return ; } int mid=(l+r)/2; build(v*2,l,mid); build(v*2+1,mid+1,r); tree[v]=max(tree[v*2],tree[v*2+1]); } void update(int pos, int d, int v=1, int l=0, int r=n) { if(l==r) { if(d==-INF) tree[v]=d; else tree[v]=max(tree[v],d); return ; } int mid=(l+r)/2; if(pos<=mid) update(pos,d,v*2,l,mid); else update(pos,d,v*2+1,mid+1,r); tree[v]=max(tree[v*2],tree[v*2+1]); } int query(int le, int ri, int v=1, int l=0, int r=n) { if(ri<l or r<le) return -INF; if(le<=l and r<=ri) return tree[v]; int mid=(l+r)/2; return max(query(le,ri,v*2,l,mid),query(le,ri,v*2+1,mid+1,r)); } }tree; int cen; void dfs1(int curr, int par) { int sz1,sz2; tie(sz1,sz2)=sizes(curr,cen); chmax(out[min(sz1,sz2)*2],h[curr]); chmax(out[sz1*2],h[curr]+tree.query(sz1,n)); for(int nxt: adj[curr]) { if(nxt==par or banned[nxt]) continue; dfs1(nxt,curr); } } vector<int> rollback; void dfs2(int curr, int par) { int sz1=sizes(curr,cen).first; tree.update(sz1,h[curr]); rollback.push_back(sz1); for(int nxt: adj[curr]) { if(nxt==par or banned[nxt]) continue; dfs2(nxt,curr); } } void cd(int curr) { dfs_sz(curr,0); curr=get_centroid(curr,0,sz[curr]); cen=curr; h[curr]=0; dfs_sz(curr,0); //cout<<"->"<<curr<<"\n"; //for(int i=1;i<=n;i++) cout<<i<<":"<<h[i]<<" "<<from[i]<<"\n"; for(int nxt: adj[curr]) { if(banned[nxt]) continue; dfs1(nxt,curr); dfs2(nxt,curr); } for(int x: rollback) tree.update(x,-INF); rollback.clear(); banned[curr]=1; for(int nxt: adj[curr]) { if(banned[nxt]) continue; cd(nxt); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0); cin>>n; for(int i=1;i<n;i++) { int u,v; cin>>u>>v; adj[u].push_back(v); adj[v].push_back(u); } lca_precalc(); tree.build(); cd(1); int start=n; if(start%2==1) start--; for(int i=start-2;i>=2;i--) out[i]=max(out[i],out[i+2]); for(int i=1;i<=n;i++) out[i]++; for(int i=1;i<=n;i++) cout<<out[i]<<"\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...