其实题目挺裸的,很简单就是要用到好多的模板,也好基本做个总结
嗯,这就是这道题需要用到的知识点,其他的就很裸了。
还有就是提一下组合数的求法,因为mod的是999911658不是质数,是合数所以把它分解为几个质数然后分别求最后用中国剩余定理再来算就好了。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const LL Mod=999911659ll;
LL mm[15]={0,2ll,3ll,4679ll,35617ll,999911659ll},M=999911658ll,A[15],ji[6][100021];
LL exgcd(LL a,LL b,LL& g,LL& x,LL& y){
if(b==0){g=a;x=1,y=0;}
else {
exgcd(b,a%b,g,y,x);y-=x*(a/b);
}
}
LL mull(LL x,LL y,LL d){
LL ans=1;
for(;y;y>>=1){
if(y&1)ans=ans*x%mm[d];
x=x*x%mm[d];
}
return ans;
}
LL Q(LL x,LL d){return mull(x,mm[d]-2,d);}
LL crt(){
LL ans=0,x,y,g,mi;
for(int i=1;i<=4;i++){
mi=M/mm[i];
exgcd(mi,mm[i],g,x,y);
ans=(ans+x*mi*A[i])%M;
}
return ans;
}
LL C(LL n,LL m,LL d){
if(n<m)return 0;
return ji[d][n]*Q(ji[d][m]*ji[d][n-m]%mm[d],d)%mm[d];
}
LL lucas(LL n,LL m,LL d){
if(m==0)return 1;
return lucas(n/mm[d],m/mm[d],d)*C(n%mm[d],m%mm[d],d)%mm[d];
}
LL make(LL n){
LL ans=0;
for(LL a,b,i=1;i*i<=n;i++){
if(n%i==0){
b=-1;
a=i;if(i*i!=n)b=n/i;
for(int k=1;k<=4;k++){
A[k]=lucas(n,a,k);
}
ans=(ans+crt())%M;
if(b!=-1){
for(int k=1;k<=4;k++){
A[k]=lucas(n,b,k);
}
ans=(ans+crt())%M;
}
}
}
ans=ans+M;
return ans;
}
int main(){
LL N,G;
for(int i=1;i<=4;i++){
ji[i][0]=1;
for(int j=1;j<=50000;j++)ji[i][j]=ji[i][j-1]*j%mm[i];
}
scanf("%I64d%I64d",&N,&G);
LL k=make(N);G%=mm[5];
printf("%I64d",mull(G,k,5));
return 0;
}