Problem:
Score : 600 points

Problem Statement

We have a tree with N vertices numbered 1 to N. The i-th edge in this tree connects Vertex a_i and b_i.
For each k=1, ..., N, solve the problem below:

Consider writing a number on each vertex in the tree in the following manner:

First, write 1 on Vertex k.

Then, for each of the numbers 2, ..., N in this order, write the number on the vertex chosen as follows:

Choose a vertex that still does not have a number written on it and is adjacent to a vertex with a number already written on it. If there are multiple such vertices, choose one of them at random.

Find the number of ways in which we can write the numbers on the vertices, modulo (10^9+7).

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq a_i,b_i \leq N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}

Output

For each k=1, 2, ..., N in this order, print a line containing the answer to the problem.

Sample Input 1

3
1 2
1 3

Sample Output 1

2
1
1

The graph in this input is as follows:

For k=1, there are two ways in which we can write the numbers on the vertices, as follows:

Writing 1, 2, 3 on Vertex 1, 2, 3, respectively

Writing 1, 3, 2 on Vertex 1, 2, 3, respectively

Sample Input 2

2
1 2

Sample Output 2

1
1

The graph in this input is as follows:

Sample Input 3

5
1 2
2 3
3 4
3 5

Sample Output 3

2
8
12
3
3

The graph in this input is as follows:

Sample Input 4

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

Sample Output 4

40
280
840
120
120
504
72
72

The graph in this input is as follows:

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Authentication.ExtendedProtection;
using System.Text;
using System.Threading;

namespace AtCoder
{
	public class Program
	{
		static void Main()
		{
			var cin = new Scanner();
			int n = cin.Int();

			ModCounting.InitializeFactorial(n);

			var reroot = new Rerooting<Virtex>(
				n,
				(x, y) => {
					int count = x.Count + y.Count;
					ModInt combination = ModCounting.Factorial(count)
						* x.Combination
						* y.Combination
						* ModCounting.InverseFactorial(x.Count)
						* ModCounting.InverseFactorial(y.Count);
					return new Virtex { Count = count, Combination = combination };
				},
				x => {
					return new Virtex { Count = x.Count + 1, Combination = x.Combination };
				},
				new Virtex { Count = 0, Combination = 1 });

			for (int i = 0; i < n - 1; i++) {
				int a = cin.Int() - 1;
				int b = cin.Int() - 1;
				reroot.AddEdge(a, b);
				reroot.AddEdge(b, a);
			}

			var ans = reroot.Build();
			var sb = new StringBuilder();
			for (int i = 0; i < n; i++) {
				sb.AppendLine(ans[i].Combination.ToString());
			}

			Console.Write(sb.ToString());
		}

		struct Virtex
		{
			public int Count { get; set; }
			public ModInt Combination { get; set; }
		}
	}

	public class Rerooting<T>
	{
		private readonly int n_;
		private readonly Func<T, T, T> merge_;
		private readonly Func<T, T> calculate_;
		private readonly T unit_;
		private readonly List<int>[] to_;
		private readonly T[][] dp_;
		private readonly T[] result_;
		private int[] reverseIndexes_;

		public Rerooting(
			int n,
			Func<T, T, T> merge,
			Func<T, T> calculate,
			T unit)
		{
			n_ = n;
			merge_ = merge;
			calculate_ = calculate;
			unit_ = unit;

			to_ = new List<int>[n];
			dp_ = new T[n][];
			result_ = new T[n];
			for (int i = 0; i < n; i++) {
				to_[i] = new List<int>();
				result_[i] = unit_;
			}
		}

		public void AddEdge(int a, int b)
		{
			to_[a].Add(b);
		}

		public T[] Build(int root = 0, bool doseOnlyTreeDp = false)
		{
			DfsForTreeDP(root);
			if (doseOnlyTreeDp == false) {
				BfsForReroot(root);
			}

			return result_;
		}

		private void DfsForTreeDP(int v)
		{
			var parents = new int[n_];
			var indexes = new int[n_];
			reverseIndexes_ = new int[n_];
			var visited = new bool[n_];
			var routeStack = new Stack<int>(n_);
			var tempStack = new Stack<int>(n_);
			routeStack.Push(v);
			tempStack.Push(v);
			visited[v] = true;
			parents[v] = -1;

			while (tempStack.Count > 0) {
				int current = tempStack.Pop();
				dp_[current] = new T[to_[current].Count];
				for (int i = 0; i < to_[current].Count; i++) {
					int next = to_[current][i];
					if (visited[next]) {
						reverseIndexes_[current] = i;
						continue;
					}

					visited[next] = true;
					parents[next] = current;
					indexes[next] = i;
					routeStack.Push(next);
					tempStack.Push(next);
				}
			}

			while (routeStack.Count > 0) {
				int target = routeStack.Pop();
				T accum = unit_;
				for (int i = 0; i < to_[target].Count; i++) {
					int child = to_[target][i];
					if (child == parents[target]) {
						continue;
					}

					accum = merge_(accum, dp_[target][i]);
				}

				result_[target] = calculate_(accum);
				if (parents[target] >= 0) {
					dp_[parents[target]][indexes[target]] = result_[target];
				}
			}
		}

		private void BfsForReroot(int first)
		{
			int max = 0;
			for (int i = 0; i < n_; i++) {
				max = Math.Max(max, to_[i].Count);
			}

			var accumL = new T[max + 1];
			var accumR = new T[max + 1];

			var q = new Queue<BfsInfo>(n_);
			q.Enqueue(new BfsInfo(first, -1));
			while (q.Count > 0) {
				var current = q.Dequeue();
				int count = to_[current.V].Count;

				accumL[0] = unit_;
				for (int i = 0; i < count; i++) {
					accumL[i + 1] = merge_(accumL[i], dp_[current.V][i]);
				}

				accumR[count] = unit_;
				for (int i = count - 1; i >= 0; i--) {
					accumR[i] = merge_(accumR[i + 1], dp_[current.V][i]);
				}

				result_[current.V] = calculate_(accumL[count]);

				for (int i = 0; i < count; i++) {
					int next = to_[current.V][i];
					if (next == current.P) {
						continue;
					}

					T reverse = calculate_(merge_(accumL[i], accumR[i + 1]));
					dp_[next][reverseIndexes_[next]] = reverse;

					q.Enqueue(new BfsInfo(next, current.V));
				}
			}
		}

		private struct BfsInfo
		{
			public int V { get; set; }
			public int P { get; set; }

			public BfsInfo(int v, int p)
			{
				V = v;
				P = p;
			}
		}
	}

	public static class ModCounting
	{
		private const long p_ = ModInt.P;

		private static ModInt[] factorial_;
		private static ModInt[] inverseFactorial_;
		private static ModInt[] inverse_;

		public static void InitializeFactorial(long max, bool withInverse = false)
		{
			if (withInverse) {
				factorial_ = new ModInt[max + 1];
				inverseFactorial_ = new ModInt[max + 1];
				inverse_ = new ModInt[max + 1];

				factorial_[0] = factorial_[1] = 1;
				inverseFactorial_[0] = inverseFactorial_[1] = 1;
				inverse_[1] = 1;
				for (int i = 2; i <= max; i++) {
					factorial_[i] = factorial_[i - 1] * i;
					inverse_[i] = p_ - inverse_[p_ % i] * (p_ / i);
					inverseFactorial_[i] = inverseFactorial_[i - 1] * inverse_[i];
				}
			} else {
				factorial_ = new ModInt[max + 1];
				inverseFactorial_ = new ModInt[max + 1];

				factorial_[0] = factorial_[1] = 1;
				for (int i = 2; i <= max; i++) {
					factorial_[i] = factorial_[i - 1] * i;
				}

				inverseFactorial_[max] = new ModInt(1) / factorial_[max];
				for (long i = max - 1; i >= 0; i--) {
					inverseFactorial_[i] = inverseFactorial_[i + 1] * (i + 1);
				}
			}
		}

		public static ModInt Factorial(long n)
		{
			if (n < 0) {
				return 0;
			}

			return factorial_[n];
		}

		public static ModInt InverseFactorial(long n)
		{
			if (n < 0) {
				return 0;
			}

			return inverseFactorial_[n];
		}

		public static ModInt Inverse(long n)
		{
			if (n < 0) {
				return 0;
			}

			return inverse_[n];
		}

		public static ModInt Permutation(long n, long k)
		{
			if (n < k || (n < 0 || k < 0)) {
				return 0;
			}

			return factorial_[n] * inverseFactorial_[n - k];
		}

		public static ModInt RepeatedPermutation(long n, long k)
		{
			long ret = 1;
			for (k %= p_ - 1; k > 0; k >>= 1, n = n * n % p_) {
				if ((k & 1) == 1) {
					ret = ret * n % p_;
				}
			}

			return ret;
		}

		public static ModInt Combination(long n, long k)
		{
			if (n < k || (n < 0 || k < 0)) {
				return 0;
			}

			return factorial_[n] * inverseFactorial_[k] * inverseFactorial_[n - k];
		}

		public static ModInt CombinationK(long n, long k)
		{
			ModInt ret = 1;
			for (int i = 0; i < k; i++) {
				ret *= (n - i);
				ret *= inverse_[i + 1];
			}

			return ret;
		}

		public static ModInt HomogeneousProduct(long n, long k)
		{
			if (n < 0 || k < 0) {
				return 0;
			}

			return Combination(n + k - 1, k);
		}
	}

	public struct ModInt
	{
		public const long P = 1000000007;
		//public const long P = 998244353;

		public static ModInt Inverse(ModInt value) => Pow(value, P - 2);
		public static ModInt Pow(ModInt value, long k) => Pow(value.value_, k);
		public static ModInt Pow(long value, long k)
		{
			long ret = 1;
			for (k %= P - 1; k > 0; k >>= 1, value = value * value % P) {
				if ((k & 1) == 1) {
					ret = ret * value % P;
				}
			}
			return new ModInt(ret);
		}

		private long value_;

		public ModInt(long value)
			=> value_ = value;
		public ModInt(long value, bool mods)
		{
			if (mods) {
				value %= P;
				if (value < 0) {
					value += P;
				}
			}

			value_ = value;
		}

		public static ModInt operator +(ModInt lhs, ModInt rhs)
		{
			lhs.value_ = (lhs.value_ + rhs.value_) % P;
			return lhs;
		}
		public static ModInt operator +(long lhs, ModInt rhs)
		{
			rhs.value_ = (lhs + rhs.value_) % P;
			return rhs;
		}
		public static ModInt operator +(ModInt lhs, long rhs)
		{
			lhs.value_ = (lhs.value_ + rhs) % P;
			return lhs;
		}

		public static ModInt operator -(ModInt lhs, ModInt rhs)
		{
			lhs.value_ = (P + lhs.value_ - rhs.value_) % P;
			return lhs;
		}
		public static ModInt operator -(long lhs, ModInt rhs)
		{
			rhs.value_ = (P + lhs - rhs.value_) % P;
			return rhs;
		}
		public static ModInt operator -(ModInt lhs, long rhs)
		{
			lhs.value_ = (P + lhs.value_ - rhs) % P;
			return lhs;
		}

		public static ModInt operator *(ModInt lhs, ModInt rhs)
		{
			lhs.value_ = lhs.value_ * rhs.value_ % P;
			return lhs;
		}
		public static ModInt operator *(long lhs, ModInt rhs)
		{
			rhs.value_ = lhs * rhs.value_ % P;
			return rhs;
		}
		public static ModInt operator *(ModInt lhs, long rhs)
		{
			lhs.value_ = lhs.value_ * rhs % P;
			return lhs;
		}

		public static ModInt operator /(ModInt lhs, ModInt rhs)
		{
			long exp = P - 2;
			while (exp > 0) {
				if (exp % 2 > 0) {
					lhs *= rhs;
				}

				rhs *= rhs;
				exp /= 2;
			}

			return lhs;
		}

		public static implicit operator ModInt(long n) => new ModInt(n, true);
		public long ToLong() => value_;
		public override string ToString() => value_.ToString();
	}

	public class HashMap<TKey, TValue> : Dictionary<TKey, TValue>
	{
		private readonly Func<TKey, TValue> initialzier_;
		public HashMap(Func<TKey, TValue> initialzier)
			: base()
		{
			initialzier_ = initialzier;
		}

		public HashMap(Func<TKey, TValue> initialzier, int capacity)
			: base(capacity)
		{
			initialzier_ = initialzier;
		}

		new public TValue this[TKey key]
		{
			get
			{
				if (ContainsKey(key) == false) {
					base[key] = initialzier_(key);
				}

				return base[key];
			}

			set { base[key] = value; }
		}
	}

	public static class Helper
	{
		public static void UpdateMin<T>(ref T target, T value) where T : IComparable<T>
			=> target = target.CompareTo(value) > 0 ? value : target;

		public static void UpdateMin<T>(ref T target, T value, Action<T> onUpdated) where T : IComparable<T>
		{
			if (target.CompareTo(value) > 0) {
				target = value;
				onUpdated(value);
			}
		}

		public static void UpdateMax<T>(ref T target, T value) where T : IComparable<T>
			=> target = target.CompareTo(value) < 0 ? value : target;
		public static void UpdateMax<T>(ref T target, T value, Action<T> onUpdated) where T : IComparable<T>
		{
			if (target.CompareTo(value) < 0) {
				target = value;
				onUpdated(value);
			}
		}

		public static T[] Array<T>(int n, Func<int, T> init)
			=> Enumerable.Range(0, n).Select(x => init(x)).ToArray();
		public static List<T> List<T>(int n, Func<int, T> init)
			=> Enumerable.Range(0, n).Select(x => init(x)).ToList();
		public static T[,] Array2<T>(int n, int m, T init)
		{
			var array = new T[n, m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					array[i, j] = init;
				}
			}

			return array;
		}

		public static T[,] Array2<T>(int n, int m, Func<int, int, T> initializer)
		{
			var array = new T[n, m];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < m; j++) {
					array[i, j] = initializer(i, j);
				}
			}

			return array;
		}

		public static T[,,] Array3<T>(int n1, int n2, int n3, T init)
		{
			var array = new T[n1, n2, n3];
			for (int i1 = 0; i1 < n1; i1++) {
				for (int i2 = 0; i2 < n2; i2++) {
					for (int i3 = 0; i3 < n3; i3++) {
						array[i1, i2, i3] = init;
					}
				}
			}

			return array;
		}

		private static readonly int[] delta4_ = { 1, 0, -1, 0, 1 };
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void DoAt4(int i, int j, int imax, int jmax, Action<int, int> action)
		{
			for (int dn = 0; dn < 4; dn++) {
				int d4i = i + delta4_[dn];
				int d4j = j + delta4_[dn + 1];
				if ((uint)d4i < (uint)imax && (uint)d4j < (uint)jmax) {
					action(d4i, d4j);
				}
			}
		}

		private static readonly int[] delta8_ = { 1, 0, -1, 0, 1, 1, -1, -1, 1 };
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void DoAt8(int i, int j, int imax, int jmax, Action<int, int> action)
		{
			for (int dn = 0; dn < 8; dn++) {
				int d8i = i + delta8_[dn];
				int d8j = j + delta8_[dn + 1];
				if ((uint)d8i < (uint)imax && (uint)d8j < (uint)jmax) {
					action(d8i, d8j);
				}
			}
		}
	}

	public class Scanner
	{
		private readonly char[] delimiter_ = new char[] { ' ' };
		private readonly string filePath_;
		private readonly Func<string> reader_;
		private string[] buf_;
		private int index_;

		public Scanner(string file = "")
		{
			if (string.IsNullOrWhiteSpace(file)) {
				reader_ = Console.ReadLine;
			} else {
				filePath_ = file;
				var fs = new StreamReader(file);
				reader_ = fs.ReadLine;
			}
			buf_ = new string[0];
			index_ = 0;
		}

		public string NextLine() => reader_();
		public string Next()
		{
			if (index_ < buf_.Length) {
				return buf_[index_++];
			}

			string st = reader_();
			while (st == "") {
				st = reader_();
			}

			buf_ = st.Split(delimiter_, StringSplitOptions.RemoveEmptyEntries);
			if (buf_.Length == 0) {
				return Next();
			}

			index_ = 0;
			return buf_[index_++];
		}

		public int Int() => int.Parse(Next());
		public long Long() => long.Parse(Next());
		public double Double() => double.Parse(Next());

		public int[] ArrayInt(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Int() + add;
			}
			return Array;
		}

		public long[] ArrayLong(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Long() + add;
			}
			return Array;
		}

		public double[] ArrayDouble(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Double() + add;
			}
			return Array;
		}

		public void Save(string text)
		{
			if (string.IsNullOrWhiteSpace(filePath_)) {
				return;
			}

			File.WriteAllText(filePath_ + "_output.txt", text);
		}
	}
}