洛谷 P1593 因子和 题解

题面

这道题在数学方面没什么难度:

对于每一个正整数n:

质因数分解后可以写成n=a1^k1a2^k2……*ai^ki

所求的数的因数和f(n)就等于f(n)=(1+a1+a1^2+……+a1^k1)(1+a2+a2^2+……+a2^k2)……*(1+ai+ai^2+……+ai^ki)

利用等比数列通项公式可以O(1)的时间算出每一项;

然后可以使用扩展欧几里得,费马小定理或求解逆元。

但,仅仅是这样吗?

注意,模数p是9901,十分的小,但是要求逆元的数完全可能是9901的倍数,从而与9901不互质,从而没有逆元

例如:950497 1 ans=2;

在处理完以上的特殊情况后我们可以十分生气的一边骂出题人一边AC掉它;

#include <bits/stdc++.h>
#define int long long
#define p 9901
using namespace std;
long long KSM(long long a,long long b)
{
    long long res=1;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b/=2;
    }
    return res;
}
long long yinzi[1110],cnt,num[1010];
void fenjie(int a)
{
    for(int i=2;i<=sqrt(a);i++){
        if(a%i==0){
            yinzi[++cnt]=i;
            while(a%i==0){
                ++num[cnt];
                a/=i;
            }
        }
    }
    if(a>=1){
        yinzi[++cnt]=a;
        num[cnt]=1;
    }
}
signed main()
{
    int a,b;
    cin>>a>>b;
    fenjie(a);
    for(int i=1;i<=cnt;i++){
        num[i]=num[i]*b;
    }
    long long ans=1;
    for(int i=1;i<=cnt;i++){
        ans=(ans*(1-KSM(yinzi[i],num[i]+1))%p*KSM((1-yinzi[i]),p-2))%p;
    }
    if(ans==0){
        cout<<"2"<<endl;
        return 0;
    }
    cout<<ans;
}
原文地址:https://www.cnblogs.com/kamimxr/p/11506164.html