洛谷 P2715 约数和(唯一分解定理+等比数列求和+乘法逆元)
用逆元的看这里!
还是和前面几个一样:
因为要取模,所以除法要换成逆元,然后我就愉快地写完交了上去,60分,4个WA,发现,逆元求出来之后可以是负的,也可以是零,于是就加了这么一个特判:
if(num2<=0)num2+=p;(其中num2是我求的逆元,p是模数)
然后就AC了,根本不需要他们说的什么奇怪的逆元方式。。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
ll ksm(ll a,ll b,ll p){
ll ans=1;
a%=p;
while(b){
if(b&1){
ans=(ans*a)%p;
}
a=(a*a)%p;
b>>=1;
}
return ans;
}
const ll p=9901;
ll a,b;
ll prime[100000];
ll e[100000];
int cnt;
int main(){
scanf("%lld %lld",&a,&b);
for(ll i=2;i*i<=a;i++){
if(a%i==0){
prime[++cnt]=i;
while(a%i==0){
a/=i;
e[cnt]++;
}
e[cnt]*=b;
}
}
if(a!=1){
prime[++cnt]=a;
e[cnt]++;
e[cnt]*=b;
}
ll ans=1;
for(int i=1;i<=cnt;i++){
ll num=(ksm(prime[i],e[i]+1,p)-1+p)%p;
ll num2=ksm(prime[i]-1,p-2,p)%p;
if(num2<=0)num2+=p;
ans*=num*num2%p;
ans%=p;
}
printf("%lld",(ans+p)%p);
return 0;
}