# dfs序+线段树--青出于蓝胜于蓝

xiaoxiao2021-02-28  10

https://nanti.jisuanke.com/t/20690

### 输出格式

#include <cstdio>

#include <iostream>

#include <vector>

#include <queue>

using namespace std;

#define lc (rt << 1)

#define rc (rt << 1 | 1)

#define mid (l + r) / 2

const int maxn = 1e5 + 5;

vector<int> mp[maxn];

int f[maxn];

int te = 1;

int s[maxn],t[maxn];

int mmin[maxn << 2],mmax[maxn << 2];

int pre[maxn];

int prep = 1;

int ans[maxn];

int n,p;

void dfs(int p)

{

s[p] = ++te;

pre[prep ++] = p;

for (int i = 0; i < mp[p].size(); i ++) {

if(s[mp[p][i]] == 0) {

dfs(mp[p][i]);

}

else f[p] = mp[p][i];

}

t[p] = te;

}

void init(int l,int r,int rt)

{

if(l == r){

mmin[rt] = mmax[rt] = pre[l];

return;

}

init(l, mid, lc);

init(mid + 1, r, rc);

mmax[rt] = max(mmax[lc],mmax[rc]);

mmin[rt] = min(mmin[lc],mmin[rc]);

}

int querymmin(int ql,int qr,int l,int r,int rt)

{

if(ql <= l && r <= qr){

return mmin[rt];

}

int ans = maxn;

if(ql <= mid) ans = min(ans,querymmin(ql, qr, l, mid , lc));

if(mid < qr) ans = min(ans,querymmin(ql, qr, mid + 1, r, rc));

return ans;

}

int querymmax(int ql,int qr,int l,int r,int rt)

{

if(ql <= l && r <= qr){

return mmax[rt];

}

int ans = 0;

if(ql <= mid) ans = max(ans,querymmax(ql, qr, l, mid , lc));

if(mid < qr) ans = max(ans,querymmax(ql, qr, mid + 1, r, rc));

return ans;

}

int querycnt(int ql,int qr,int l,int r,int rt,int x)//求区间中比x小的数的个数

{

if(ql <= l && r <= qr){

if(querymmax(ql, qr, l, r, rt) < x ) return r - l + 1;

else {

if(querymmin(ql, qr, l, r, rt) >= x)return 0;

else return querycnt(ql, qr, l, mid, lc, x) + querycnt(ql, qr, mid + 1, r, rc, x);

}

}

int ans = 0;

if(ql <= mid){

ans += querycnt(ql,qr,l,mid,lc,x);

}

if(mid < qr){

ans += querycnt(ql,qr,mid + 1,r,rc,x);

}

return ans;

}

int main()

{

int a,b;

f[p] = -1;

scanf("%d%d",&n,&p);

for (int i = 0; i < n - 1; i ++) {

scanf("%d%d",&a,&b);

mp[a].push_back(b);

mp[b].push_back(a);

}

dfs(p);

init(1, n, 1);

for (int i = 1; i <= n; i ++) {

ans[pre[i]] = querycnt(s[pre[i]] - 1, t[pre[i]] - 1, 1, n,1 ,pre[i]);

//  printf("l = %d ,r = %d ,less than %d ,cnt = %d\n",s[pre[i]] - 1, t[pre[i]] - 1,pre[i],ans[pre[i]]);

}

for (int i = 1; i<= n; i ++) {

printf("%d",ans[i]);

if(i == n) printf("\n");

else printf(" ");

}

return 0;

}