-
a
n
s
=
p
∑
d
∣
n
C
n
d
%
999911659
ans=p^{\sum_{d|n}C_{n}^{d}}\%999911659
ans=p∑d∣nCnd%999911659
-
n
,
p
<
=
1
e
9
n,p<=1e9
n,p<=1e9。直接预处理阶乘肯定不行。
- 首先根据欧拉定理的推论,
a
n
s
=
p
∑
d
∣
n
C
n
d
%
999911658
%
999911659
ans=p^{\sum_{d|n}C_n^d\%999911658}\%999911659
ans=p∑d∣nCnd%999911658%999911659。
- 仍然求不了,试试能不能Lucas定理?
- 什么?你说Lucas只使用p为质数,并且p很小?把999911658拆一下啊。发现它等于
=
2
∗
3
∗
4679
∗
35617
=2*3*4679*35617
=2∗3∗4679∗35617,恰好为4个比较小的质数的乘积。这时候就可以
O
(
n
)
O(n)
O(n)预处理逆元了。
- 分开求四个答案,再用中国剩余定理合并一下,就好了。
- 记得特判
p
p
p为
999911659
999911659
999911659的倍数时直接输出0,wa了3次看题解发现。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int p1=2;
const int p2=3;
const int p3=4679;
const int p4=35617;
const int mod=999911659;
const int N=1e6+10;
ll n,g,ans1,ans2,ans3,ans4,ans;
ll jie[N];
ll power(ll a,ll b,ll p){
ll res=1;
for(;b;b>>=1){
if(b&1) res=res*a%p;
a=a*a%p;
}
return res;
}
void pre(ll p){
jie[0]=jie[1]=1;
for(int i=2;i<=1e6;++i) jie[i]=jie[i-1]*i%p;
}
ll C(ll n,ll m,ll p)
{
if(n<m) return 0;
return jie[n]*power(jie[m],p-2,p)%p*power(jie[n-m],p-2,p)%p;
}
ll lua(ll n,ll m,ll p)
{
if(n<m) return 0;if(!n) return 1;
return lua(n/p,m/p,p)*C(n%p,m%p,p)%p;
}
ll work(ll n,ll p){
ll res=0;
for(int i=1;i<=sqrt(1.0*n);++i){
if(n%i==0){
res=(res+lua(n,i,p))%p;
if(i*i!=n) res=(res+lua(n,n/i,p))%p;
}
}
return res;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1,y=0;return a;
}
ll d=exgcd(b,a%b,x,y);
ll temp=x;x=y;y=temp-y*(a/b);
return d;
}
ll CRT(){
ll M=mod-1,res=0;
ll x=0,y=0,d=0;
ll M1=M/p1;
x=power(M1,p1-2,p1);res=(res+x*ans1%M*M1%M)%M;
ll M2=M/p2;
x=power(M2,p2-2,p2);res=(res+x*ans2%M*M2%M)%M;
ll M3=M/p3;
x=power(M3,p3-2,p3);res=(res+x*ans3%M*M3%M)%M;
ll M4=M/p4;
x=power(M4,p4-2,p4);res=(res+x*ans4%M*M4%M)%M;
return res;
}
int main(){
scanf("%lld%lld",&n,&g);
if(g%mod==0){
cout<<0<<endl;
return 0;
}
pre(p1);
ans1=work(n,p1);
pre(p2);
ans2=work(n,p2);
pre(p3);
ans3=work(n,p3);
pre(p4);
ans4=work(n,p4);
ans=CRT();
cout<<power(g,ans,mod);
return 0;
}