传送门
题意 :看了题面好久,还是画了一个图才理解,意思就是根的排名为p,告诉你 n - 1 个关系,告诉你排名 ui 和 vi 是存在师徒关系。
思路:题目上给的就是排名就是 1- n ,还不用离散化,直接 dfs +树状数组 ,记录一个dfs前的状态和dfs后的状态,两个状态的差值就是答案。
附上代码:
///#include<bits/stdc++.h>
///#include<unordered_map>
///#include<unordered_set>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#include<new>
#include<vector>
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
const int INF=0x3f3f3f3f;
int n,root;
struct node
{
int e;
int p;
}load[200005];
int head[100005],sign;
void add_edge(int s,int e)
{
load[++sign]=node{e,head[s]};
head[s]=sign;
}
int bit[100005];
int cnt[100005];
void add(int i,int x)
{
while(i<=n)
{
bit[i]+=x;
i=i+(i&(-i));
}
}
int sum(int i)
{
int ans=0;
while(i>0)
{
ans+=bit[i];
i=i-(i&(-i));
}
return ans;
}
void dfs(int s,int pre)
{
cnt[s]=sum(s-1);
for(int i=head[s];~i;i=load[i].p)
{
int e=load[i].e;
if(e!=pre)
dfs(e,s);
}
cnt[s]=sum(s-1)-cnt[s];
add(s,1);
}
void init()
{
sign=0;
memset(head,-1,sizeof(head));
memset(bit,0,sizeof(bit));
memset(cnt,0,sizeof(cnt));
}
int main()
{
init();
int s,e;
scanf("%d %d",&n,&root);
for(int i=1;i<n;i++)
{
scanf("%d %d",&s,&e);
add_edge(s,e);
add_edge(e,s);
}
dfs(root,-1);
for(int i=1;i<=n;i++)
{
printf("%d",cnt[i]);
printf(i==n?"\n":" ");
}
return 0;
}