递推与递归4 约数之和

本文介绍了一种利用分治策略计算数A质因数分解后约数之和的方法,通过将问题规模从O(k)降低到O(logk),简化了计算过程。关键步骤包括定义sum(p,k)函数并递归应用。代码实例展示了如何用C++实现这一高效算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
对于一个数x,假设他分解质因数后的形式为p1a1 *p2a2 *p3a3 。则他的约数之和为(1+p1+···+p1a1)*(1+p2+···+p2a2)*(1+p3+···+p3a3)。
故本题只需要将A分解质因数,每个质因子的数量乘以B。再按照上式计算即可。
如何计算呢,我们可以依次计算每个质因子,最后相乘。但是由于A分解质因数后需要乘以B,可能会使次数很大,所以我们无法一次一次的循环。
考虑分治,对于每一个质因子,令sum(p,k)=(1+p+···+pk):
如果k是偶数,则sum(p,k)=(1+p+···+pk/2-1)+pk/2+(pk/2+1+···pk)=(1+p+···+pk/2-1)+pk/2+pk/2+1 *(1+p+···+pk/2-1)=sum(p,k/2-1)(1+pk/2+1)+pk/2
如果k是奇数,类似的sum(p,k)=sum(p,k/2)*(1+k/2+1)。
这样就将O(k)优化到了O(logk)轻松通过。
代码:

#include<bits/stdc++.h>
using namespace std;
const int mod = 9901;
typedef pair<int, int> PII;
int a,b;
int qmi(int a,int b,int p){
    a%=p;
    int res=1;
    while(b){
        if(b&1)res=res*a%p;
        b>>=1;
        a=a*a%p;
    }
    return res;
}
int sum(int p,int k){
    if(k==0)return 1;
    if(k&1)return sum(p,k/2)*(1+qmi(p,k/2+1,mod))%mod;
    return ((qmi(p,k/2+1,mod)+1)*sum(p,k/2-1)%mod+qmi(p,k/2,mod))%mod;
}
int main(){
    cin>>a>>b;
    if(a==0){
        cout<<0;
        return 0;
    }
    vector<PII>primes;
    for(int i=2;i<=a&&a>1;i++){
        if(a%i==0){
            int cnt=0;
            while(a%i==0){
                cnt++;
                a/=i;
            }
            if(b)primes.push_back({i,cnt*b});
        }  
    }
    if(a>1&&b)primes.push_back({a,b});
    int res=1;
    for(auto [p,k]:primes){
        res=res*sum(p,k)%mod;
    }
    cout<<res;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值