Ultraviolet A 1436-counting heaps
Question Link
Given the structure of a tree, place 1-N numbers in it. The value of the parent node must be smaller than that of the child node.
Train of Thought: F [u] indicates the case where U is the subtree, then the subtree is F (V1), F (V2), F (V3 )... F (VN ). to form a subtree is equivalent to selecting S (V1), S (V2), S (V3 )... S (VN ). F (V1) f (V2 )... F (VN) (S (u)-1 )! \ (S (V1 )! S (V2 )! ... * S (VN )!) The formula is obtained after simplification:
F (u) = (S (Root)-1 )! /S (1) S (2) S (3)... S (n)
Because the answer is very big to m, but M is not a prime number, you cannot directly find the inverse, you can only split the denominator of the numerator into the prime factor, and finally get the de-modulo in the form of molecules.
Code:
# Include <stdio. h> # include <string. h> # include <queue> using namespace STD; const int n = 500005; int t, n, CNT [N], prime [N], vis [N], pn = 0, F [N], ispri [N]; long m; int BFS () {// use DFS to requeue <int> q; for (INT I = 1; I <= N; I ++) if (! Vis [I]) Q. Push (I); While (! Q. empty () {int now = Q. front (); q. pop (); If (now = 0) break; CNT [f [now] + = CNT [now]; vis [f [now] --; if (vis [f [now] = 0) Q. push (F [now]) ;}} void solve (INT num, int v) {for (INT I = 0; I <PN & prime [I] <= num; I ++) {While (Num % prime [I] = 0) {CNT [prime [I] + = V; num/= prime [I];} if (ispri [num]) {// without this pruning, it is inevitable that tle cnt [num] + = V; break ;}} long pow_mod (long X, int K) {long ans = 1; while (k) {If (K & 1) ans = ans * x % m; X = x * x % m; k> = 1;} return ans;} int main () {for (INT I = 2; I <n; I ++) {If (vis [I]) continue; ispri [I] = 1; prime [pn ++] = I; for (Int J = I; j <n; j + = I) vis [J] = 1;} scanf ("% d", & T); While (t --) {scanf ("% d % LLD", & N, & M); For (INT I = 1; I <= N; I ++) CNT [I] = 1; F [1] = 0; memset (VIS, 0, sizeof (VIS); For (INT I = 2; I <= N; I ++) {scanf ("% d", & F [I]); vis [f [I] ++;} BFS (); memset (VIS, 0, sizeof (VIS); For (INT I = 1; I <= N; I ++) vis [CNT [I] ++; memset (CNT, 0, sizeof (CNT); For (INT I = 2; I <= N; I ++) {solve (I, 1); If (vis [I]) solve (I,-vis [I]);} long ans = 1; for (INT I = 0; I <PN; I ++) {If (CNT [prime [I] = 0) continue; ans = (ANS * pow_mod (long) prime [I], CNT [prime [I]) % m;} printf ("% LLD \ n ", ans);} return 0 ;}