我们根据欧几里得定理可以知道
(a,b)=(b,a mod b)也可以得到
(a+b,b)=(b,(a+b) mod b)=(b,a)=(a,b)
直观点说就是两个数a,b的gcd,和a+b,b的gcd是相等的
那么我们可以知道phi(m!)也就是与1-m!中与m!互质的数,
那么对于每个互质的数,我们加上m!,就可以得到一个新的
和m!互质的数,所以对于每个1-m!与m!互质的数
n!范围内一共可以得到n!/m!组解,那么一共也就是phi(m!)*(n!/m!)
可以将phi(m!)用公式展开化简,在此不再赘述
/************************************************************** Problem: 2186 User: BLADEVIL Language: Pascal Result: Accepted Time: 9524 ms Memory: 248272 kb ****************************************************************/ // By BLADEVIL var t, r :longint; i :longint; prime : array [ 0 .. 1000001 ] of longint; flag : array [ 0 .. 10000001 ] of boolean; fac, pi1, pi2 : array [ 0 .. 10000001 ] of int64; x, y :int64; procedure make; var i, j :longint; begin fac[ 0 ]:= 1 ; flag[ 1 ]:= true; for i:= 1 to 10000000 do fac[i]:=fac[i- 1 ]*int64(i) mod r; for i:= 2 to 10000000 do begin if not flag[i] then begin inc(prime[ 0 ]); prime[prime[ 0 ]]:= i; end ; for j:= 1 to prime[ 0 ] do begin if i*prime[j]> 10000000 then break; flag[i *prime[j]]:= true; if i mod prime[j]= 0 then break; end ; end ; pi1[ 0 ]:= 1 ; pi2[ 0 ]:= 1 ; for i:= 1 to 10000000 do begin pi1[i]: =pi1[i- 1 ]; if not flag[i] then pi1[i]:=pi1[i]*int64(i- 1 ) mod r; end ; for i:= 1 to 10000000 do begin pi2[i]: =pi2[i- 1 ]; if not flag[i] then pi2[i]:=pi2[i]*int64(i) mod r; end ; end ; procedure ex_gcd(a,b:int64); var z :int64; begin if b= 0 then begin x: = 1 ; y:= 0 ; exit; end ; ex_gcd(b,a mod b); z: = x; x: = y; y: =z-(a div b)* y; end ; function gcd(a:int64):int64; begin ex_gcd(a,r); gcd: =(x mod r+r) mod r; end ; procedure main; var i :longint; ans :int64; n, m :longint; begin read(n,m); ans: = fac[n]; ans: =ans*pi1[m] mod r; ans: =ans*gcd(pi2[m]) mod r; writeln(ans); end ; begin read(t,r); make; for i:= 1 to t do main; end .