Submission #1286239

#TimeUsernameProblemLanguageResultExecution timeMemory
1286239denislavMeetings 2 (JOI21_meetings2)C++20
0 / 100
2 ms584 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][0];
}

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...