题目:
https://ac.nowcoder.com/acm/problem/20333
求
G
∑
d
∣
n
(
n
i
)
m
o
d
999911659
G^{\sum_{d|n}{n\choose i}}\ mod\;999911659
G∑d∣n(in) mod999911659
思路:
G
∑
d
∣
n
(
n
i
)
m
o
d
p
=
G
(
∑
d
∣
n
(
n
i
)
)
m
o
d
p
−
1
m
o
d
p
\begin{aligned} &G^{\sum_{d|n}{n\choose i}}\ mod\;p\\ =&G^{(\sum_{d|n}{n\choose i})mod\;p-1}\ mod\;p\\ \end{aligned}
=G∑d∣n(in) modpG(∑d∣n(in))modp−1 modp
p
−
1
=
2
×
3
×
4697
×
35617
p-1=2×3×4697×35617
p−1=2×3×4697×35617
中国剩余定理
+
L
u
c
a
s
+Lucas
+Lucas求
∑
d
∣
n
(
n
i
)
≡
x
m
o
d
p
−
1
⟺
{
∑
d
∣
n
(
n
m
o
d
2
i
m
o
d
2
)
≡
x
m
o
d
2
∑
d
∣
n
(
n
m
o
d
3
i
m
o
d
3
)
≡
x
m
o
d
3
∑
d
∣
n
(
n
m
o
d
4697
i
m
o
d
4697
)
≡
x
m
o
d
4697
∑
d
∣
n
(
n
m
o
d
35617
i
m
o
d
35617
)
≡
x
m
o
d
35617
\sum_{d|n}{n\choose i}\equiv x\ mod\;p-1\Longleftrightarrow \begin{cases} \sum_{d|n}{n\;mod\;2\choose i\;mod\;2}\equiv x\ mod\;2\\ \sum_{d|n}{n\;mod\;3\choose i\;mod\;3}\equiv x\ mod\;3\\ \sum_{d|n}{n\;mod\;4697\choose i\;mod\;4697}\equiv x\ mod\;4697\\ \sum_{d|n}{n\;mod\;35617\choose i\;mod\;35617}\equiv x\ mod\;35617\\ \end{cases}
∑d∣n(in)≡x modp−1⟺⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧∑d∣n(imod2nmod2)≡x mod2∑d∣n(imod3nmod3)≡x mod3∑d∣n(imod4697nmod4697)≡x mod4697∑d∣n(imod35617nmod35617)≡x mod35617
最后再用一下快速幂即可。
注意:
当
G
=
p
G=p
G=p时,输出
0
0
0。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int mod=999911658;
LL n,G,farc[50010],a[5],b[5]={0,2,3,4679,35617},val;
LL fast_pow(LL a,LL b,LL p)//快速幂
{
LL ret=1;
for(;b;b>>=1,a=a*a%p)
ret=ret*(b&1?a:1)%p;
return ret;
}
void init(LL p)//预处理
{
farc[0]=1;
for(LL i=1;i<=p;i++)
farc[i]=farc[i-1]*i%p;
}
LL C(LL n,LL m,LL p)//组合数
{
if(n<m) return 0;
return farc[n]*fast_pow(farc[m],p-2,p)%p*fast_pow(farc[n-m],p-2,p)%p;
}
LL Lucas(LL n,LL m,LL p)//Lucas定理
{
if(n<m) return 0;if(!n) return 1;
return Lucas(n/p,m/p,p)*C(n%p,m%p,p)%p;
}
void CRT()//中国剩余定理
{
for(LL i=1;i<=4;i++)
val=(val+a[i]*(mod/b[i])%mod*fast_pow(mod/b[i],b[i]-2,b[i]))%mod;
}
int main()
{
scanf("%lld%lld",&n,&G);
if(G%(mod+1)==0){
printf("0\n");
return 0;
}//特判
for(LL k=1;k<=4;k++){
init(b[k]);
for(LL i=1;i*i<=n;i++){
if(n%i==0){
a[k]=(a[k]+Lucas(n,i,b[k]))%b[k];
if(i*i!=n){
a[k]=(a[k]+Lucas(n,n/i,b[k]))%b[k];
}
}
}
}//逐一枚举n的约数
CRT();
printf("%lld\n",fast_pow(G,val,mod+1));//注意mod要+1
return 0;
}