Given n (n <= 10 ^ 9) beads and M colors, the N beads can form a necklace, and each bead can be filled with M colors, if the two coloring methods are obtained by rotating the necklace, the two coloring methods are equivalent. Now, the K group restriction is given. Each group of restriction A and B indicates that color a and color B cannot be coated on adjacent beads. How many coloring methods are available.
Solution: This question is roughly the same as that of poj2154. The difference is that there is a restriction here, that is, two colors may not be painted on adjacent beads. In this case, we can use matrix concatenation to first initialize the matrix array [I] [J] as 1. if colors A and B cannot be coated with adjacent beads, array [a] [B] = array [B] [a] = 0; for replacement with N/L cyclic knots (L is the length of each cyclic section ). First obtain the N/L power of array [] [], and then the array [I] [I] (1 <= I <= m) of this matrix) the sum of all is the number of coloring methods that remain unchanged under this replacement.
From above: http://hi.baidu.com/ofeitian/blog/item/694770caf3da47f052664fca.html
Supplement:
The k power of a indicates the path in which the graph length is K. If it returns to itself, it indicates the loop in which the length is K. I have learned discrete mathematics.
But why can we use this path to find "replace the number that keeps the color unchanged"?
Assume that a 10th order replacement F can be divided into five rotations: [1, 2] [3, 4] [5, 6] [7, 8] [9, 10]. At the same time, we can find a color loop with a length of 5 (A, B, C, D, E ).
Then we can use a to color [1, 2], B to [3, 4], and C to color [5, 6 ····.
Therefore, each loop can provide a coloring method, and such a coloring method remains unchanged after replacement by F.
So we can add up the total number of loops and keep the total number of colors unchanged.
In addition, do not forget to divide by the total number of replicas. Because gcd (n, 9973) = 1, find the reverse yuan and then OK ···
# Include <cmath> # include <cstring> # include <algorithm> # include <iostream> # include <cstdio> using namespace STD; const int maxn = 1000000; const int modulo = 9973; int A [maxn], p [maxn], PN; Class cmatrix {public: int data [11] [11], n; cmatrix (INT, INT); cmatrix operator * (const cmatrix &) const; cmatrix power (INT) const ;}; cmatrix: cmatrix (int f, int size) {n = size; memset (data, 0, sizeof (data); If (F = 0) return; For (INT I = 0; I <11; I ++) data [I] [I] = 1 ;}// note the sparse matrix optimization cmatrix:: Operator * (const cmatrix 1_m) const {cmatrix RET (0, n); For (INT I = 0; I <n; I ++) for (Int J = 0; j <n; j ++) {for (int K = 0; k <n; k ++) ret. data [I] [J] + = data [I] [k] * Param. data [k] [J]; ret. data [I] [J] % = modulo;} return ret;} // quickly calculate the power cmatrix: Power (INT exp) const {cmatrix RET (1, N ); cmatrix TMP = (* This); While (exp> 0) {If (exp & 1) ret = RET * TMP; TMP = TMP * TMP; exp >>=1 ;} return ret;} void prime () {int I, j; Pn = 0; memset (A, 0, sizeof (a); for (I = 2; I <maxn; I ++) {If (! A [I]) P [pn ++] = I; for (j = 0; j <PN & I * P [J] <maxn & (P [J] <= A [I] | A [I] = 0 ); j ++) A [I * P [J] = P [J] ;}} int Euler (int n) {int I, ret = N; for (I = 0; I <PN & P [I] * P [I] <= N; I ++) {If (N % P [I] = 0) {ret = ret-RET/P [I]; while (N % P [I] = 0) n/= P [I] ;}} if (n> 1) ret = ret-RET/N; return ret % modulo;} int loop (const cmatrix &, int L) {int ret = 0; cmatrix TMP =. Power (l); For (INT I = 0; I <TMP. n; I ++) RET + = TMP. data [I] [I]; return ret % modulo;} int ext_gcd (int A, int B, Int & X, Int & Y) {int ret, TMP; if (B = 0) {x = 1, y = 0; return a;} ret = ext_gcd (B, A % B, x, y); TMP = X, X = Y, y = TMP-A/B * Y; return ret;} int inverse (INT N) {int X, Y; ext_gcd (n, modulo, X, y); X = x % modulo; return x> = 0? X: x + modulo;} int polyA (const cmatrix & A, int N, int m) {int ret = 0; For (int l = 1; L * l <= N; l ++) {If (N % L) continue; ret = (Ret + Euler (l) * loop (A, N/L )) % modulo; If (L * l = N) break; ret = (Ret + Euler (N/L) * loop (A, L) % modulo ;} return ret * inverse (n) % modulo;} int main () {Prime (); int n, m, K, Cs, X, Y; scanf ("% d ", & CS); While (Cs --) {scanf ("% d", & N, & M, & K); cmatrix A (0, M ); for (INT I = 0; I <m; I ++) for (Int J = 0; j <m; j ++). data [I] [J] = 1; while (k --) {scanf ("% d", & X, & Y);. data [x-1] [Y-1] =. data [Y-1] [x-1] = 0;} printf ("% d \ n", polyA (A, n, m);} return 0 ;}