Poj_2888
At the beginning, I was too impetuous to learn polyA. It was just a formula. In fact, it was not based on understanding. Today, I read the black book again, and finally I was able to deduce the polyA formula based on the Burnside theorem.
To solve this problem, first understand the content of the Burnside theorem, and then use the DP Method to Calculate the so-called C (f) in the black book (the number of coloring schemes that remain unchanged under F). The final result is the average value of C (f), that is, C (f)/n. Due to the mutual quality of 9973 and N, We can first obtain the inverse element of N, then we can get the value of (C (f)/n) % 9973.
We recommend that you use this blog: http://hi.baidu.com/billdu/item/62319f2554c7cac9a5275a0d.
# Include <stdio. h> # Include < String . H> # Include <Math. h># Include <Algorithm> # Define Maxd 40010 # Define Maxm 15 # Define Mod4 9973 Using Namespace STD; Int N, m, K, prime [maxd], isprime [maxd], p, G [maxm] [maxm], d [maxd], D; Struct Matrix { Int A [maxm] [maxm]; Void Init () {memset (, 0 , Sizeof (A) ;}} unit, mat; Void Prepare (){ Int I, J, K = 40000 ; P = 0 ; Memset (isprime, - 1 , Sizeof (Isprime )); For (I = 2 ; I <= K; I ++ ) If (Isprime [I]) {Prime [p ++] = I; For (J = I * I; j <= K; j + = I) isprime [J] = 0 ;}} Int Euler ( Int N ){ Int I, ANS, X; ans = X = N; For (I = 0 ; I <P & prime [I] * prime [I] <= N; I ++ ) If (X % prime [I] = 0 ) {Ans = ANS/prime [I] * (Prime [I]- 1 ); While (X % prime [I] = 0 ) X /= Prime [I];} If (X> 1 ) Ans = ANS/x * (X- 1 ); Return Ans ;} Void Exgcd ( Int A, Int B, Int & X, Int & Y ){ If (B = 0 ) X = 1 , Y = 0 ; Else Exgcd (B, % B, Y, x), Y-= x * (/ B);} matrix multiply (Matrix & X, Matrix & Y ){ Int I, J, K; Matrix Z; Z. INIT (); For (I = 0 ; I <m; I ++ ) For (K = 0 ; K <m; k ++ ) If (X. A [I] [k]) { For (J = 0 ; J <m; j ++ ) If (Y. A [k] [J]) Z. A [I] [J] = (Z. A [I] [J] + X. A [I] [k] * Y. A [k] [J]) % MOD ;} Return Z ;} Void Init (){ Int I, X, Y; scanf ( " % D " , & N, & M ,& K); memset (G, - 1 , Sizeof (G )); For (I = 0 ; I <K; I ++) {Scanf ( " % D " , & X ,& Y ); -- X ,-- Y; G [x] [Y] = G [y] [x] = 0 ;}} Void Divide ( Int N ){ Int I, J; d = 0 ; For (I = 1 ; I * I <= N; I ++ ) If (N % I = 0 ) {D [d ++] = I; If (N/I! = I) d [d ++] = N/ I;} Sort (D, D + D );} Void Powmod (Matrix & unit, Matrix & mat,Int N ){ While (N ){ If (N & 1 ) Unit = Multiply (MAT, Unit); n >>= 1 ; MAT = Multiply (MAT, mat );}} Void Solve (){ Int I, j, X, Y, N, ANS =0 ; Divide (N ); For (I = 0 ; I <D; I ++ ) {N = Euler (N/d [I]) % MOD; For (X = 0 ; X <m; X ++ ) For (Y = 0 ; Y <m; y ++ ) Mat. A [x] [Y] =- G [x] [Y]; Unit = MAT; powmod (unit, mat, d [I] - 1 ); For (J = 0 ; J <m; j ++ ) Ans = (ANS + N * Unit. A [J] [J]) % MOD;} exgcd (n, Mod, x, y); x = (X % mod + mod) % MOD; ans = (ANS * X) % MOD; printf ( " % D \ n " , ANS );} Int Main (){ Int T; prepare (); scanf ( " % D " ,& T ); While (T -- ) {Init (); solve ();} Return 0 ;}