传送门

题意 :看了题面好久,还是画了一个图才理解,意思就是根的排名为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;
}