2018 Blue Bridge Cup Simulation Tournament · Blue is better than blue DFS sequence + tree array

The Wudang faction has a total of nnn people, within thesectThe n people are ranked according to the level of martial arts, and the person with the highest martial arts ranks11th1 , the second highest ranked22nd2 , ... The person with the lowest martial arts ranksnnn . Now we use the ranking of martial arts to label everyone. Except for the ancestors, everyone has a master, and everyone may have multiple apprentices.

We know that Wudang sent talents in large numbers, and even the martial arts of the ancestors can only be ranked in ppp . That is to say, the martial arts of the apprentice may surpass that of the master. The so-called youth is better than the blue.

Please help to calculate how many of each person's apprentices (including apprentices' apprentices, apprentices' apprentices' apprentices....) have more martial arts than himself.

input format

Enter the first line of two integers n,p(1≤n≤100000,1≤p≤n)n, p(1 \le n \le 100000, 1 \le p \le n)n,p(1n100000,1pn)

Next n−1n-1n 1 lines, each line input two integersu,v(1≤u,v≤n)u, v(1 \le u, v \le n)u , v ( 1 u , v n ) , representinguuuvvThere is a mentoring relationship between v .

output format

output a line nnn integers,iithi integers indicate that the martial arts ranking isiiHow many children of the man of i surpassed him.

Do not output extra spaces at the end of the line .

sample input

10 5
5 3
5 8
3 4
3 1
2 1
6 7
8 7
9 8
8 10

Sample output

0 0 2 0 4 0 1 2 0 0

The meaning of the question is to give us a tree and let us find the number of nodes that are smaller than themselves in all child nodes.

You can find the parent nodes of all nodes under dfs, and then each point keeps looking up the parent node until the root is found. The complexity is close to the square level of n, and it will definitely time out.
in order not to time out
We can figure out the DFS order of the whole tree, and then the difference between the pre-order and post-order of any node is the number of child nodes of this point
But what we are looking for is the node that is smaller than him in the child node
那么我们就可以dfs序和树状数组配合起来 dfs序把树形问题转化成了区间上的问题
我们知道这个点的先序和后序位次 那么如果有比他小的节点在这个节点的先序和后序之间遍历到了
那么一定是符合要求的点
所以我们可以从小大到处理点 对于每个点查询先序后序位置中树状数组存储的差
然后再把当前节点的先序插入进去  这样的好处就是先遍历标号小的节点 先把小的节点的先序插到树状数组
树状数组维护的就是当前节点先序插入时的次序 因为我们是通过前序后序间符合条件的点数来求解的


import java.util.ArrayList;
import java.util.Scanner;
import java.util.Vector;

public class Main {
	final static int maxn = 100010; 
	public static int [] tre = new int[maxn];
	public static ArrayList<Integer>[] gra = new ArrayList[maxn];//存图
	public static boolean[] bok = new boolean[maxn];
	public static boolean[] vis = new boolean[maxn];
	public static int[] l = new int[maxn];//记录先序
	public static int[] r = new int[maxn];//记录第二次回溯回来时的顺序
	public static int time =0 ;
	static void DFS(int now) {
		l[now] = ++time;
		for(int i=0;i<gra[now].size();i++) {
			int t = gra[now].get(i);
			if(!vis[t]) {
				vis[t]=true;
				DFS(t);
				vis[t]=false;
			}
		}
		r[now] = time;
	}
	static void add(int x) {
		while(x<maxn) {
			tre[x]+=1;
			x+=x&(-x);
		}
	}
	static int sum(int x) {
		int S=0;
		while(x!=0) {
			S+=tre[x];
			x-=x&(-x);
		}
		return S;
	}
	public static void main(String[] args) {
		int n,p;
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		p = sc.nextInt();
		for(int i=1;i<n;i++) {
			int s,e;
			s = sc.nextInt();
			e = sc.nextInt();
			if(bok[s]==false) {
				bok[s] = true;
				gra[s] = new ArrayList<Integer>();
				gra[s].add(e);
			}
			else gra[s].add(e);
			if(bok[e]==false) {
				bok[e] = true;
				gra[e] = new ArrayList<Integer>();
				gra[e].add(s);
			}
			else gra[e].add(s);
		}
		vis[p]=true;
		DFS(p);
		for(int i=1;i<=n;i++) {
			System.out.print(sum(r[i])-sum(l[i]));
			add(l[i]);
			if(i==n)System.out.println();
			else System.out.print(" ");
		}
	}
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325763031&siteId=291194637