首先假设输入的是n,m
我们就是要求m^(Σ(c(n,i) i|n)) mod p
那么根据费马小定理,上式等于
m^(Σ(c(n,i) i|n) mod (p-1)) mod p
那么问题的关键就是求 Σ(c(n,i) i|n) mod (p-1)了
那么如果P是素数的话,我们可以用lucas定理来快速求出来组合数,这道题的p-1是
非素数,那么我们分解质因数pi,假设c(n,i) i|n为X,那我们求出来X mod pi=ai,这个是
符合lucas定理的,那么我们可以得到质因子数个式子(本题有4个质因子),然后我们用
中国剩余定理合并这4个式子就行了
/************************************************************** Problem: 1951 User: BLADEVIL Language: Pascal Result: Accepted Time: 108 ms Memory: 540 kb ****************************************************************/ // By BLADEVIL const d39 = 999911659 ; pp : array [ 1 .. 4 ] of longint=( 2 , 3 , 4679 , 35617 ); var n, m, k :int64; cc :int64; a : array [ 0 .. 10 ] of int64; i :longint; fac : array [ 0 .. 40000 ] of int64; function ex_gcd(a,b:int64):int64; var z :int64; begin if b= 0 then begin ex_gcd: = 1 ; cc: = 0 ; exit; end else begin z: =ex_gcd(b,a mod b); ex_gcd: = cc; cc: =z-(a div b)* cc; end ; end ; function gcd(a,p:int64):int64; begin gcd: = ex_gcd(a,p); gcd: =(gcd mod p+p) mod p; end ; function combine(a,b,p:int64):int64; var ans1, ans2 :int64; i :longint; begin ans1: =fac[a] mod p; ans2: =(fac[a-b]*fac[b]) mod p; ans2: = gcd(ans2,p); combine: =ans1*ans2 mod p; end ; function lucas(x,y,p:int64):int64; var a, b :int64; begin if y= 0 then exit( 1 ); a: =x mod p; b: =y mod p; if a<b then exit( 0 ) else lucas:=lucas(x div p,y div p,p)* combine(a,b,p); end ; function crt:int64; var i :longint; begin crt: = 0 ; for i:= 1 to 4 do crt: =(crt+a[i]*((d39- 1 ) div pp[i])*gcd((d39- 1 ) div pp[i],pp[i])) mod (d39- 1 ); end ; function get(x:int64):int64; var i, j :longint; begin for i:= 1 to trunc(sqrt(x)) do begin if x mod i= 0 then begin for j:= 1 to 4 do begin a[j]: =(a[j]+lucas(x,i,pp[j])) mod pp[j]; if x div i<>i then a[j]:=(a[j]+lucas(x,x div i,pp[j])) mod pp[j]; end ; end ; end ; get: = crt; end ; function mi(n,k,p:int64):int64; var sum :int64; begin mi: = 1 ; sum: = n; while k<> 0 do begin if k mod 2 = 1 then mi:=mi*sum mod p; sum: =sum*sum mod p; k: =k div 2 ; end ; end ; begin fac[ 0 ]:= 1 ; for i:= 1 to pp[ 4 ] do fac[i]:=fac[i- 1 ]*int64(i) mod (d39- 1 ); read(n,m); if m mod d39= 0 then begin writeln( 0 ); halt; end ; k: = get(n); writeln(mi(m,k,d39)); end .