Posted onSymbols count in article: 1.2kReading time ≈4 mins.
Problem
Cowmpany Cowmpensation
TimeLimit:2seconds MemoryLimit:256megabytes
Description
Allen, having graduated from the MOO Institute of Techcowlogy (MIT), has started a startup! Allen is the president of his startup. He also hires n−1 other employees, each of which is assigned a direct superior. If u is a superior of v and v is a superior of w then also u is a superior of w. Additionally, there are no u and v such that u is the superior of v and v is the superior of u. Allen himself has no superior. Allen is employee number 1, and the others are employee numbers 2 through n.
Finally, Allen must assign salaries to each employee in the company including himself. Due to budget constraints, each employee’s salary is an integer between 1 and D. Additionally, no employee can make strictly more than his superior.
Help Allen find the number of ways to assign salaries. As this number may be large, output it modulo 109+7.
Input
The first line of the input contains two integers n and D (1≤n≤3000, 1≤D≤109).
The remaining n−1 lines each contain a single positive integer, where the ith line contains the integer pi (1≤pi≤i). pi denotes the direct superior of employee i+1.
Output
Output a single integer: the number of ways to assign salaries modulo 109+7.
Example
Input #1
1 2 3
3 2 1 1
Output #1
1
5
Input #2
1 2 3
3 3 1 2
Output #2
1
10
Input #3
1 2
2 5 1
Output #3
1
15
Note
In the first sample case, employee 2 and 3 report directly to Allen. The three salaries, in order, can be (1,1,1), (2,1,1), (2,1,2), (2,2,1) or (2,2,2).
In the second sample case, employee 2 reports to Allen and employee 3 reports to employee 2. In order, the possible salaries are (1,1,1), (2,1,1), (2,2,1), (2,2,2), (3,1,1), (3,2,1), (3,2,2), (3,3,1), (3,3,2), (3,3,3).
#include<bits/stdc++.h> #define MAX_N 3000 #define P 1000000007 usingnamespace std; typedeflonglong lnt; template <classT> inlinevoidread(T &x){ x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int n, m; vector <int> G[MAX_N+5]; lnt f[MAX_N+5][MAX_N+5]; lnt fac[MAX_N+5], inv[MAX_N+5]; voidinit(int n){ fac[0] = inv[0] = inv[1] = 1; for (int i = 1; i <= n; i++) fac[i] = fac[i-1]*i%P; for (int i = 2; i <= n; i++) inv[i] = (P-P/i*inv[P%i]%P)%P; for (int i = 2; i <= n; i++) inv[i] = inv[i]*inv[i-1]%P; } voidDFS(int u){ for (int x = 1; x <= n; x++) f[u][x] = 1; for (int i = 0; i < (int)G[u].size(); i++) { int v = G[u][i]; DFS(v); for (int x = 1; x <= n; x++) f[u][x] = f[u][x]*f[v][x]%P; } for (int x = 1; x <= n; x++) f[u][x] = (f[u][x]+f[u][x-1])%P; } #define getL(i) (i < n ? pre[n-i-1] : 1) #define getR(i) (i > 0 ? suc[n-i+1] : 1) lnt Poly_Inter(){ lnt ret = 0; lnt pre[MAX_N+5], suc[MAX_N+5]; pre[0] = m-n, suc[n] = m; for (int i = 1; i <= n-1; i++) pre[i] = pre[i-1]*(m-n+i)%P; for (int i = n-1; i >= 1; i--) suc[i] = suc[i+1]*(m-n+i)%P; for (int i = 0, c = (n&1) ? -1 : 1; i <= n; i++, c = -c) ret = (ret+c*getL(i)*getR(i)%P*inv[i]%P*inv[n-i]%P*f[1][i]%P)%P; return (ret+P)%P; } intmain(){ read(n), read(m), init(n); for (int i = 2, x; i <= n; i++) read(x), G[x].push_back(i); DFS(1), printf("%lld\n", Poly_Inter()); return0; }