TZOJ: 5845:A^B的约数和(二分法求等比数列前n项和)

本文介绍了一种利用质因数分解求解整数约数之和的方法。通过将目标整数分解为质因数的幂次乘积形式,并利用等比数列求和公式来高效计算约数之和。文中详细阐述了算法步骤,并提供了完整的C++代码实现。

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

题面

第一步:对A进行质因数分解,并将其存入map中

map<LL,LL> maps;
void get_prime(int n){
    for(int i=2;i<=n;i++){
        if(n%i==0){
            int ans=0;
            while(n%i==0){
                n=n/i;
                ans++;
            }
            maps[i]+=ans;
        }
    }
    if(n>1) maps[n]++;
}

第二步:

当 A= p1^a1 + p2^a2 + p3^a3....pm^am;

那么 A^b= p1^(a1 * b) + p2^(a2 * b) + ... + pm^(am * b);

那么约数之和就等于(1 + p1 + p1^1 + p1^2 +...+ p1^(a1 * b))*(1 + p2 + ....);

那么就变成了求以p1(p2,p3...)为公比的等比数列前n项和;

假如项数为n:

当n==0时,根据题意要输出1,如果首项为p,那么当n==0时应当输出0;

当n=奇数,会有偶数项,我们把1和p^(n/2+1)放在一起 p和p^(n/2+1+1)放在一起,以此类推
最后提公因式,得到【1+p^(n/2+1)】*【1+p+p^2+p^3+....+p^(n/2-1)】右边恰为原式的一半

当n=偶数,可以由奇数的情况推过来.若用sum(p,k)表示公比为p的前k+1项和(首项为1),那么

sum(p,k)=p*sum(p,k-1)+1;
因此二分递归则可以得到答案
 

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod=9901;
map<LL,LL> maps;
void get_prime(int n){
    for(int i=2;i<=n;i++){
        if(n%i==0){
            int ans=0;
            while(n%i==0){
                n=n/i;
                ans++;
            }
            maps[i]+=ans;
        }
    }
    if(n>1) maps[n]++;
}
LL qpow(LL a,LL k){
    if(k==0) return 1;
    LL t=qpow(a,k/2);
    if(k%2==0) return t*t%mod;
    return t*t%mod*a%mod;
}
LL sum(LL p,LL k){
    if(k==0) return 1;
    if(k%2==0) return (p%mod*sum(p,k-1)+1)%mod;
    return (1+qpow(p,k/2+1))*sum(p,k/2)%mod;
}
int main(){
    LL a,b;
    cin>>a>>b;
    get_prime(a);
    LL res=1;
    for(map<LL,LL>::iterator it=maps.begin();it!=maps.end();it++){
        LL x=it->first,y=it->second;
        res=res*sum(x,y*b)%mod;
    }
    cout<<res<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值