1951: [Sdoi2010] Ancient pig wen
Seeking G^sigma{c (N, i), I | N} The value of mod m, where m = 999911659.
M is a prime number, so according to Fermat theorem g^ (M-1) ≡1 (mod M).
Then G^sigma{c (N, i), I | n}≡g^ (Sigma{c (N, i), I | n} mod (M-1)) ≡g^sigma{c (n, i) mod (M-1), I | N} (mod M). So we only need C (N, K) mod (M-1) and then accumulate.
Note: M-1 = 2 * 3 * 4679 * 35617.
So we can get
P≡A1 (mod 2)
P≡A2 (mod 3)
P≡A3 (mod 4679)
P≡A4 (mod 35617)
After the A1,A2,A3,A4 is obtained, it can be merged by the Chinese remainder theorem.
Desire A1,a2,a3,a4 We only need C (N, K) mod p (P is prime) (n,k<= 10^10)
N,k is very big, we can solve this problem by Lucas theorem
Calc (n,m,p) = C (n%p,m%p) * Calc (n/p,m/p,p);
Then C (n,m) is solved directly by preprocessing factorial + multiplication inverse element;
In addition: when the G = = M when the Pegasus small theorem is not set to output 0;
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <
Assert.h> using namespace std;
typedef long Long Lint;
Lint P,n,g;
Lint A[10] = {2,3,4679,35617};
Lint fac[40000];
Inline Lint pow (lint x,lint y,lint p) {Lint res (1);
x%= p;
while (y) {if (y&1) res = (res*x)%p;
x = (x*x)%p;
Y >>= 1;
} return res%p;
} Inline Lint C (lint N,lint m,lint p) {if (M > N) return 0;
if (!m) return 1;
Lint res (1);
res = res * Fac[n]% P;
res = res * POW (fac[m]*fac[n-m]%p,p-2,p)% p;
return res;
} Inline Lint Calc (lint N,lint m,lint p) {if (M > N) return 0;
if (m = = 0 | | m = = n) return 1;
Return Calc (n/p,m/p,p) *c (n%p,m%p,p)%p;
} Inline Lint Get_ans (lint n,lint m) {Lint res (0);
for (Lint i = 0; i < 4; i++) res = (res + (p/a[i)) *pow (p/a[i],a[i]-2,p)%p*calc (N,m,a[i])%P)%P;
Return (res%p+p)%P;
} inline Lint Solve () {if (g% (p+1) = = 0) return 0;
Lint pw = 0;
for (Lint i = 1; I * i <= n; i++) if (n%i = = 0) {if (i * i = = N) pw = (pw + get_ans (n,i))%P;
else PW = (pw + Get_ans (n,i) + Get_ans (n,n/i))%P;
} return Pow (g,pw,p+1);
} int main () {P = 999911658;
Fac[0] = 1;
for (Lint i = 1; I <= a[3]; i++) fac[i] = fac[i-1] * I% P;
cin>>n>>g;
Cout<<solve () <<endl;
return 0;
}