洛谷 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;
}
posted @ 2017-09-14 20:38  玫葵之蝶  阅读(173)  评论(0编辑  收藏  举报