「CF1109F」Dominant Indices【樹上啓發式合併】

F. Dominant Indices

time limit per test 4.5 seconds
memory limit per test 512 megabytes
input standard input
output standard output

You are given a rooted undirected tree consisting of nn vertices. Vertex 11 is the root.

Let’s denote a depth array of vertex xx as an infinite sequence [dx,0,dx,1,dx,2,],[d_{x,0},d_{x,1},d_{x,2},…], where dx,id_{x,i} is the number of vertices yy such that both conditions hold:

  • xx is an ancestor of yy;
  • the simple path from xx to yy traverses exactly ii edges.

The dominant index of a depth array of vertex xx (or, shortly, the dominant index of vertex xx) is an index jj such that:

  • for every k<j,dx,k<dx,jk<j, d_{x,k}<d_{x,j};
  • for every k>j,dx,kdx,j.k>j, d_{x,k}\leq d_{x,j}.

For every vertex in the tree calculate its dominant index.

Input

The first line contains one integer n (1n106)n\ (1\leq n\leq 10^6) — the number of vertices in a tree.

Then n1n−1 lines follow, each containing two integers xx and yy (1x,yn,x!=y).(1\leq x,y\leq n, x!=y). This line denotes an edge of the tree.

It is guaranteed that these edges form a tree.

Output

Output nn numbers. ithi-th number should be equal to the dominant index of vertex ii.

Examples

input
4
1 2
2 3
3 4
output
0
0
0
0
input
4
1 2
1 3
1 4
output
1
0
0
0
input
4
1 2
2 3
2 4
output
2
1
0
0

題意

  • 就是給你一顆有根樹,對於每一顆子樹,統計每一個深度下的節點數,求有最多節點的深度hh,如果節點數有相同的選深度小的那個

題解

  • 樹上啓發式合併模板題
  • 對於相同節點的深度,可以直接用10610^6setset去維護節點數爲ii的所有深度,然後就能方便的去撤銷子樹的信息
  • 複雜度n(logn)2n(\log n)^24.5s4.5s剛剛好

代碼

#include<bits/stdc++.h>
 
using namespace std;
const int maxn=2e6+10;

//題目數據
int t,n,u,v,q,k,a[maxn],b[maxn],ans[maxn],cnt[maxn],sum,maxx=0,he=0,cnth[maxn],pos[maxn];
vector<int> vec[maxn];

//樹剖用
int tot=0,siz[maxn],son[maxn];
int vis[maxn];

void dfs1(int cur,int fath,int he){ //dfs(root,0,1)
    siz[cur]=1;
    for(int i=0;i<vec[cur].size();i++){
        if(vec[cur][i]!=fath){
            dfs1(vec[cur][i],cur,he+1);
            siz[cur]+=siz[vec[cur][i]];
            if(siz[vec[cur][i]]>siz[son[cur]]) son[cur]=vec[cur][i];
        }
    }
}

void calc(int cur,int fa,int val,int h)
{
    if(val==1) {
        if(cnth[h]) pos[cnth[h]].erase(h);
        cnth[h]++;
        pos[cnth[h]].insert(h);
        if(cnth[h]>maxx) {maxx=cnth[h];he=(*pos[cnth[h]].begin());}
        else if(cnth[h]==maxx) he=(*pos[cnth[h]].begin());
    }else {
        pos[cnth[h]].erase(h);
        cnth[h]--;
        pos[cnth[h]].insert(h);
        if(!pos[cnth[h]+1].size()&&maxx==cnth[h]+1) {
            maxx=cnth[h];
            he=(*pos[cnth[h]].begin());
        }else if(maxx==cnth[h]) {
            he=(*pos[cnth[h]].begin());
        }
    }
    for(int i=0;i<vec[cur].size();i++){
        if(vec[cur][i]!=fa&&!vis[vec[cur][i]]){  
            calc(vec[cur][i],cur,val,h+1);
        }
    }
}

void dfs(int cur,int fa,bool keep,int h) 
{
    for(int i=0;i<vec[cur].size();i++){
        if(vec[cur][i]!=fa&&vec[cur][i]!=son[cur]){
            dfs(vec[cur][i],cur,0,h+1);
        }
    }
    if(son[cur]) dfs(son[cur],cur,1,h+1),vis[son[cur]]=1; 
    calc(cur,fa,1,h);
    ans[cur]=he-h; 
    if(son[cur]) vis[son[cur]]=0;  
    if(!keep) calc(cur,fa,-1,h);  
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d %d",&u,&v);
        vec[u].push_back(v);
        ec[v].push_back(u);
    }
    dfs1(1,0,1);
    dfs(1,0,0,1);
    for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章