solution
理解完题意。发现就是求(g^{sumlimits_{k|n}C_n^k})。
利用欧拉降幂,可以将式子写成(g^{sumlimits_{k|n}C_n^k\%phi(mod)})
只要想办法把指数求出来就行了。
看一下数据范围,发现(n)比较大,不能直接计算组合数。然后考虑用(lucas)。但是模数也比较大。
因为模数不是质数,对其进行质因数分解得到(2,3,4679,35671)。发现这四个质数都是可以进行(lucas)的。所以思路就很明显了,先将模数分解质因子,然后分别求出答案。得到四个形如(sumlimits_{k|n}C_n^kequiv a_i(mod m_i))的式子。然后用(CRT)将其合并起来,得到(sumlimits_{k|n}C_n^k\%phi(mod))
PS:因为欧拉降幂必须满足底数与模数互质,因为题目所给模数为质数,所以当(g)为所给模数倍数时不能使用欧拉降幂,而此时答案显然为(0),需要特判。
code
/*
* @Author: wxyww
* @Date: 2020-04-22 09:31:36
* @Last Modified time: 2020-04-22 09:52:12
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 100010;
ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0'; c = getchar();
}
return x * f;
}
ll qm(ll x,ll y,ll mod) {
ll ret = 1;
for(;y;y >>= 1,x = x * x % mod)
if(y & 1) ret = ret * x % mod;
return ret;
}
int jc[N],inv[N];
ll C(int n,int m,int mod) {
if(n < m) return 0;
if(n < mod) return jc[n] * inv[m] % mod * inv[n - m] % mod;
return C(n % mod,m % mod,mod) * C(n / mod,m / mod,mod) % mod;
}
ll a[5];
ll b[5] = {0,2,3,4679,35617};
ll solve(int n,int mod) {
jc[0] = 1;
for(int i = 1;i < mod;++i) jc[i] = jc[i - 1] * i % mod;
inv[mod - 1] = qm(jc[mod - 1],mod - 2,mod);
// cout<<inv[mod - 1]<<endl;
for(int i = mod - 2;i >= 0;--i) inv[i] = inv[i + 1] * (i + 1) % mod;
ll ret = 0;
for(int i = 1;i * i <= n;++i) {
if(n % i) continue;
ret += C(n,i,mod);
ret %= mod;
if(i * i != n) ret += C(n,n / i,mod),ret %= mod;
// if(mod == 2) {
// printf("!!%d
",C(n,i,mod));
// }
}
return ret;
}
int main() {
int n = read(),G = read();
if(G % 999911659 == 0) {
puts("0");return 0;
}
for(int i = 1;i <= 4;++i) {
a[i] = solve(n,b[i]);
// printf("%d
",a[i]);
}
ll M = 999911658;
ll ans = 0;
for(int i = 1;i <= 4;++i) {
ans += a[i] * (M / b[i]) % M * qm(M / b[i],b[i] - 2,b[i]) % M;
ans %= M;
}
cout<<qm(G,ans,M + 1);
return 0;
}