思路:
首先一眼dfs序,转化成序列问题来解决这是没有问题的
但是我在如何求徒弟中武功比他高的时候纠结好久。。。其实是我在dfs序中编的号和他给的武功等级让我很混乱了///
这里就运用了树状数组求逆序对的那种思想,我从武功最高的人开始(等级为1的)先看他徒弟的整个区间内是否为0,为0就代表徒弟武功都没他高,然后在把他对应的编号+1(因为我们是按照武功等级来访问的,所以如果访问师父时不为0,就说明前面访问的有他的徒弟,即武功比他高)
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int maxn = 1e5+5;
int in[maxn],out[maxn],cnt;
int s[maxn];
int n,p;
vector<int>vt[maxn];
int lowbit(int x)
{
return x & -x;
}
void add(int x,int num)
{
while(x < maxn)
{
s[x] += num;
x += lowbit(x);
}
return ;
}
int sum(int x)
{
int res = 0;
while(x)
{
res += s[x];
x -= lowbit(x);
}
return res;
}
void dfs(int x,int f)
{
in[x] = ++cnt;
for(int i = 0;i < vt[x].size();++i)
{
int v = vt[x][i];
if(v == f) continue;
dfs(v,x);
}
out[x] = cnt;
return ;
}
int main()
{
while(~scanf("%d %d",&n,&p))
{
for(int i = 0;i <= n;++i)
vt[i].clear();
for(int i = 1;i < n;++i)
{
int u,v;
scanf("%d %d",&u,&v);
vt[u].pb(v);
vt[v].pb(u);
}
cnt = 0;
dfs(p,-1);
for(int i = 1;i <= n;++i)
{
int ans = sum(out[i]) - sum(in[i] - 1);
printf("%d%c",ans,i == n?'\n':' ');
add(in[i],1);
}
}
return 0;
}