제출 #1286228

#제출 시각아이디문제언어결과실행 시간메모리
1286228denislavMeetings 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; int n; vector<int> adj[MAX]; int out[MAX]; int spec,add_spec; bool banned[MAX]; int sz[MAX]; int h[MAX]; int from[MAX]; void dfs_sz(int curr, int par) { sz[curr]=1; for(int nxt: adj[curr]) { if(nxt==par or banned[nxt]) continue; if(from[curr]==0) from[nxt]=nxt; else from[nxt]=from[curr]; h[nxt]=h[curr]+1; dfs_sz(nxt,curr); sz[curr]+=sz[nxt]; } if(curr==spec) sz[curr]+=add_spec; } 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 N; void dfs1(int curr, int par) { int sz1=sz[curr],sz2=N-sz[from[curr]]; 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=sz[curr]; 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, int special) { spec=-1; dfs_sz(curr,0); N=sz[curr]; curr=get_centroid(curr,0,sz[curr]); spec=special; add_spec=n-N; from[curr]=0; 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,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); } tree.build(); cd(1,-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...