欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

约数之和

程序员文章站 2022-05-08 19:17:45
...

博客已搬迁至空白之间

假设现在有两个自然数A和B,S是AB的所有约数之和。
请你求出S mod 9901的值是多少。

输入格式
在一行中输入用空格隔开的两个整数A和B。

输出格式
输出一个整数,代表S mod 9901的值。

数据范围
0≤A,B≤5×10^7
输入样例:
2 3
输出样例:
15
注意: A和B不会同时为0。

思路:
1、将S分解质因数
S = a ^ b = p1 ^ ( k1 * b) * p2 ^ (k2 * b)……pn ^(kn * b)
其中p1、p2、……pn都是a的质因数
2、由约数和公式我们可知
res = (1 + p1 ^ 1 + p1 ^ 2 +……p1 ^ (k1 * b))
……
( 1 + pn ^ 1 + pn ^ 2 +…… pn ^ (kn * b) )
3、我们令sum(p , k) = (1 + p ^ 1 + p ^ 2 + p ^ 3 + …… + p ^ k)
4、当k是偶数的时候,我们可以推出来
sum(p , k) = (1 + p ^ (k / 2)) * sum(p , k / 2) - p ^ (k / 2);
5、当k是奇数的时候,我们可以推出来
sum(p , k) = (1 + p ^ ( (k + 1) / 2 ) ) * sum(p , (k - 1) / 2)
ps:这题要特判a是0的时候
代码:

#include <iostream>
#include <unordered_map>

using namespace std;

const int mod = 9901;
typedef long long LL;


LL qmi(LL a , LL b)
{
    LL res = 1;
    while(b)
    {
        if(b & 1)
            res = res * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}

LL sum(LL p ,LL k)
{
    if(k == 0)
        return 1;
    if(k % 2 == 0)
        return ((1 + qmi(p , k / 2)) * sum(p , k / 2) - qmi(p , k / 2)) % mod;
    else
        return (1 + qmi(p , (k + 1) / 2)) * sum(p , (k - 1) / 2) % mod;
}

int main(void)
{
    LL a , b , res = 1;
    unordered_map<int , int >mp;
    
    cin >> a >> b;
    if(a == 0)
    {
        cout << 0 << endl;
        return 0;
    }
    
    for(int i = 2 ; i <= a / i ; i++)
        while(a % i == 0)
        {
            mp[i] += 1;
            a /= i;
        }
    if(a > 1) mp[a] += 1;
    
    for(auto t : mp)
        res = res * sum(t.first , t.second * b) % mod;
    cout << res << endl;
    return 0;
}