码迷,mamicode.com
首页 > 其他好文 > 详细

约数之和

时间:2020-01-29 19:32:11      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:int   ++   分治   efi   name   因数分解   names   mes   ace   

众所周知计算正整数\(A\)约数和的方法是:

\(A\)质因数分解为\(p_1^{c_1} p_2^{c_2} p_3^{c_3} \cdots p_m^{c_m}\)

\(A\)的约数和即为\((1 + p_1 + p_1^2 + \cdots + p_1^{c_1}) * (1 + p_2 + p_2^2 + \cdots + p_2^{c_2}) * (1 + p_2 + p_2^2 + \cdots + p_2^{c_2}) * \cdots * (1 + p_m + p_m^2 + \cdots + p_m^{c_m})\)

记得李煜东给了个分治求等比数列求和的方法, 大概就是将利用数列是等比的, 利用较短数列的和求出较长数列的和, 具体实现有一些细节.


#include<bits/stdc++.h>
using namespace std;

#define int long long

const int mod = 9901;

int ksm(int a, int b)
{
    int res = 1; a%=mod;
    for(;b;b>>=1, a=(a*a)%mod)
        if(b & 1) res = (res * a) % mod;
    return res % mod;
}

int sum(int p, int c)
{
    if(c == 1) return 1;
    int smer = sum(p, c>>1);
    int now = (smer + smer * ksm(p, c>>1) % mod) % mod;
    if(c&1) now = (now + ksm(p, c-1)) % mod;
    return now % mod;
}

signed main()
{
    
    int a, b; cin >> a >> b;
    
    if(!a)
    {
        cout << 0;
        return 0;
    }
    
    int ans = 1;
    for(int i=2; i<=a; ++i)
    {
        int s = 0;
        while(a%i == 0) ++s, a/=i;
        ans = ans * sum(i, s * b + 1) % mod;
    }
    
    cout << ans % mod;
    return 0;
    
}

约数之和

标签:int   ++   分治   efi   name   因数分解   names   mes   ace   

原文地址:https://www.cnblogs.com/tztqwq/p/12238758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!