Submission #595714

#TimeUsernameProblemLanguageResultExecution timeMemory
595714czhang2718Meetings 2 (JOI21_meetings2)C++17
100 / 100
1026 ms34216 KiB
#include "bits/stdc++.h"
using namespace std;

const int N=2e5+1;
int n;
vector<int> adj[N];
int ans[N+2];
bool vis[N];
int sz[N];
int dist[N];
int add[N];
int dp[N];
pair<int,int> mx[N], mx2[N];
int MR[N];

#define f first
#define s second

void dfs1(int x, vector<int> &nodes){
    vis[x]=1;
    nodes.push_back(x);
    sz[x]=1;
    for(int k:adj[x]){
        if(vis[k]) continue;
        dfs1(k, nodes);
        sz[x]+=sz[k];
    }
}

void dfs2(int x, int cnt, int &c){
    vis[x]=1;
    for(int k:adj[x]){
        if(vis[k]) continue;
        if(sz[k]>cnt/2){
            dfs2(k, cnt, c);
            if(c) return;
        }
    }
    if(!c) c=x;
}

void dfs3(int x, vector<int> &no, vector<int> &undo){
    no.push_back(x);
    vis[x]=1;
    for(int k:adj[x]){
        if(vis[k]) continue;
        dist[k]=dist[x]+1;
        dfs3(k, no, undo);
    }
    undo.push_back(sz[x]);
    // cout << "sz " << x << " " << sz[x] << "\n";
    dp[sz[x]]=max(dp[sz[x]], dist[x]);
}

void dfs4(int x){
    vis[x]=1;
    sz[x]=add[x];
    for(int k:adj[x]){
        if(vis[k]) continue;
        dfs4(k);
        sz[x]+=sz[k];
    }
}

void go(int x){
    vector<int> nodes;
    // get nodes and subtree sz
    dfs1(x, nodes);
    if(nodes.size()==1) return;

    // find centroid
    for(int u:nodes) vis[u]=0;
    int c=0;
    dfs2(x, nodes.size(), c);

    // cout << "centroid " << c << "\n";
    // for(int i:nodes) cout << i << " ";
    // cout << "\n";

    // get real sizes
    for(int u:nodes) vis[u]=0;
    dfs4(c);

    // combine subtrees
    for(int u:nodes) if(u!=c) vis[u]=0;
    vector<int> sizes;
    vector<int> root;
    for(int k:adj[c]){
        if(vis[k]) continue;
        vector<int> nodes2;
        dist[k]=1;
        root.push_back(k);
        vector<int> undo;
        dfs3(k, nodes2, undo);
        for(int v:nodes2){
            // cout << "ans " << 2*min(sz[v], sz[c]-sz[k]) << " mx= " << dist[v] << " v=" << v << "\n";
            ans[2*min(sz[v], sz[c]-sz[k])]=max(ans[2*min(sz[v], sz[c]-sz[k])], dist[v]);
        }
        sort(undo.begin(), undo.end());
        undo.erase(unique(undo.begin(), undo.end()), undo.end());
        for(int i:undo){
            // cout << "k " << k << " TRY " << i << " " << dp[i] << "\n";
            if(dp[i]>mx[i].first) mx2[i]=mx[i], mx[i]={dp[i], k};
            else if(dp[i]>mx2[i].first) mx2[i]={dp[i], k};
        }

        for(int p:undo) dp[p]=-1, sizes.push_back(p);
    }
    sort(sizes.begin(), sizes.end());
    sizes.erase(unique(sizes.begin(), sizes.end()), sizes.end());
    reverse(sizes.begin(), sizes.end());
    
    multiset<int> s;

    for(int p:sizes){
        int v=mx[p].first;
        int i=mx[p].second;
        if(MR[i]!=-1){
            int u=MR[i];
            s.erase(s.find(u));
            MR[i]=max(MR[i], v);
            s.insert(MR[i]);
        }
        else{
            MR[i]=v;
            s.insert(MR[i]);
        }
        v=mx2[p].first;
        i=mx2[p].second;
        if(i!=-1){
            if(MR[i]!=-1){
                int u=MR[i];
                s.erase(s.find(u));
                MR[i]=max(MR[i], v);
                s.insert(MR[i]);
            }
            else{
                MR[i]=v;
                s.insert(MR[i]);
            }
        }
        

        if(s.size()>=2) ans[2*p]=max(ans[2*p], *prev(s.end())+*prev(prev(s.end())));

        mx[p]=mx2[p]={-1,-1};
    }

    for(int u:nodes) if(u!=c) vis[u]=0;
    for(int k:root) MR[k]=-1;
    for(int k:adj[c]){
        if(!vis[k]){
            add[k]+=sz[c]-sz[k];
            go(k);
        }
    }
}

int main(){
    cin.tie(0)->sync_with_stdio(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);
    }
    for(int i=1; i<=n; i++) add[i]=1, dp[i]=MR[i]=-1, mx[i]=mx2[i]={-1,-1};
    go(1);

    // for(int i=1; i<=n; i++){
    //     cout << ans[i] << " ";
    // }
    // cout << "\n";
    for(int i=n-1; i>=1; i--) ans[i]=max(ans[i], ans[i+1]);
    for(int i=1; i<=n; i++){
        if(i&1) cout << "1\n";
        else cout << 1+ans[i] << "\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...