zl程序教程

您现在的位置是:首页 >  其它

当前栏目

【约数】因子和

因子 约数
2023-09-11 14:14:52 时间

P1593 因子和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题意:

思路:

我们去枚举约数

如果直接枚举约数,超时

对于枚举约数,有两个trick:枚举倍数和唯一分解定理

我们考虑后者,对其分解质因数:

因为它又有b的幂次:

 

因此答案就是:

 

这里可以直接用等比数列求和公式:

 

因为是模意义下的答案,因此考虑逆元

但是mod=9901,容易出现逆元不存在的情况

逆元不存在时,有

 

 

因此直接代入得

 

Code:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=9901;
vector<pair<int,int> > v;
int a,b,ans=1;
int ksm(int a,int b,int mod){
    int res=1;
    while(b>0){
        if(b&1) res=(res*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return res%mod;
}
int calc(int p,int aa){
    if((1-p)%mod==0){
        return (1+aa)%mod;
    }
    int inv=ksm(1-p,mod-2,mod);
    return ((1-ksm(p,aa*b+1,mod))*inv)%mod;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>a>>b;
    if(a==0){
        cout<<0<<'\n';
        return 0;
    }
    for(int i=2;i<=a/i;i++){
        if(a%i==0){
            int s=0;
            while(a%i==0) a/=i,s++;
            v.push_back({i,s});
        }
    }
    if(a>1) v.push_back({a,1});
    //for(int i=0;i<v.size();i++) cout<<v[i].first<<" "<<v[i].second<<'\n';
    int ans=1;
    for(int i=0;i<v.size();i++){
        ans*=calc(v[i].first,v[i].second);
        ans%=mod;
    }
    cout<<(ans%mod+mod)%mod<<'\n';
}

 总结:

快速枚举约数:枚举倍数/唯一分解

数太大时考虑唯一分解

当模数比较小时要考虑逆元不存在的情况,不存在的话根据它的性质直接代入计算即可