逆元
题目大意:给你两个正整数A、B,求 AB 的所有因子之和 mod 9901 。
把A分解成质因数形式
AB=pa1B1pa2B2…panBn
一个数的质因子之和
ϕ(n)=pa1+11p1−1×pa2+12p2−1×⋯×pan+1npn−1
于是
AB=pa1B+11p1−1×pa2B+12p2−1×⋯×panB+1npn−1
然后因为每个 p 和
即 ans=abmod m=a mod (mb)/b
然后就差不多了
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 10000
#define WJD 9901//不要在意名字
using namespace std;
typedef long long LL;
LL a,b;
LL prime[MAXN+5],p,t,num[MAXN+5][2];
bool f[MAXN+5];
void Make(){//筛素数
memset(f,true,sizeof(f));
for (LL i=2;i<=MAXN;i++){
if (f[i]) prime[++p]=i;
for (LL j=1;j<=p&&prime[j]*i<=MAXN;j++){
f[i*prime[j]]=false;
if (i%prime[j]==0) break;
}
}
}
void fenjie(LL x){//质因数分解
LL node=1; memset(num,0,sizeof(num));
while (x>1&&node<=p){
if (x%prime[node]==0) num[++t][0]=prime[node];
while (x%prime[node]==0){
x/=prime[node]; num[t][1]++;
}
node++;
}
if (x>1) {
num[++t][0]=x; num[t][1]=1;
}
}
LL mul(LL a,LL b,LL m){//快速乘
LL ret=0; a%=m;
while (b){
if (b&1)
ret=(ret+a)%m;
a=(a+a)%m;
b/=2;
}
return ret;
}
LL qsm(LL a,LL b,LL m){//快速幂
LL ret=1; a%=m;
while (b){
if (b&1)
ret=mul(ret,a,m);
a=mul(a,a,m);
b/=2;
}
return ret;
}
int main(){
Make();
while (scanf("%lld%lld",&a,&b)==2){
fenjie(a); LL ans=1;
for (LL i=1;i<=t;i++){
LL M=(LL)(num[i][0]-1)*WJD;
ans*=(qsm(num[i][0],num[i][1]*b+1,M)+M-1)/(num[i][0]-1)%WJD;//求逆元把除换成乘
ans=(ans+WJD)%WJD;
}
printf("%lld\n",ans);
}
}