97. 约数之和

摘要
Title: 97. 约数之和
Tag: 数论、约数
Memory Limit: 64 MB
Time Limit: 1000 ms

Powered by:NEFU AB-IN

Link

97. 约数之和

  • 题意

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

  • 思路

    ABA^B的约数之和为:sumAB=(1+p1+p12+...+p1B×a1)×(1+p2+p22+...+p2B×a2)×...sum_{A^B} = (1 +p_1 + p_1 ^ 2 + ... + p_1^{B×a_1}) × (1 +p_2 + p_2 ^ 2 + ... + p_2^{B×a_2}) × ...
    为什么最高项是B×aB×a呢,最高项代表pp这个质因子的个数,一开始AAxxpp,那么A3=A×A×AA^3=A×A×A就有3x3xpp

    • 做法一:等比数列求和 + 快速幂

      所以,对于每个质因子,根据等比数列求和公式 (1+p+p2+...+pB×a)=pB×a+11p1(1 +p + p ^ 2 + ... + p^{B×a}) = \frac{p^{B×a+1}-1}{p-1}
      那么,对AA进行质因子分解

      • pB×a+1p^{B×a+1}快速幂
      • 1p1\frac{1}{p-1}费马小定理求逆元,但必须保证p1p-1MODMOD互质
        • p1p-1MODMOD互质,正常求即可
        • p1p-1MODMOD不互质,我们无法求逆元,就换种思路求表达式。因为 p%MOD=1p \% MOD = 1(1+p+p2+...+pB×a)%MOD=1+B×a×1=1+B×a(1 +p + p ^ 2 + ... + p^{B×a}) \% MOD= 1 + B×a ×1 = 1 + B×a,所以直接返回1+B×a1 + B×a即可

      复杂度 O(nlog(n))O(\sqrt{n}log(n))

    • 做法二:分治 + 快速幂
      定义 sum(p,k)=(1+p+p2+...+pk)sum(p, k) = (1 +p + p ^ 2 + ... + p^{k}),共k+1k +1

      • kk奇数时,项数为偶数,以下默认k2=k2\frac{k}{2} =\lfloor \frac{k}{2} \rfloor
        原式=(p0+p1+...+pk2)+(pk2+1+...+pk)=(p0+p1+...+pk2)+pk2+1×(p0+p1+...+pk2)=(1+pk2+1)×sum(p,k2)=(p^0+p^1+...+p^{\frac{k}{2}}) +(p^{\frac{k}{2} +1}+...+p^k) = (p^0+p^1+...+p^{\frac{k}{2}}) + p^{\frac{k}{2} +1} × (p^0+p^1+...+p^{\frac{k}{2}}) = (1 + p^{\frac{k}{2} +1} ) × sum(p, \frac{k}{2})
      • kk偶数时,转化为奇数情况,sum(p,k)=sum(p,k1)+pksum(p,k) = sum(p ,k - 1) + p^k

      复杂度 O(nlog(n)log(n))O(\sqrt{n}log(n)log(n))

    • 超时做法三:递推
      (p0+p1+...+pk)(p^0+p^1+...+p^k),可用递推式,ans = ans * p + 1,但此做法会超时

  • 代码

    做法一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    /*
    * @Author: NEFU AB-IN
    * @Date: 2023-02-18 11:22:46
    * @FilePath: \Acwing\97\97.cpp
    * @LastEditTime: 2023-02-18 23:11:41
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #undef int

    #define SZ(X) ((int)(X).size())
    #define ALL(X) (X).begin(), (X).end()
    #define IOS \
    ios::sync_with_stdio(false); \
    cin.tie(nullptr); \
    cout.tie(nullptr)
    #define DEBUG(X) cout << #X << ": " << X << '\n'
    typedef pair<int, int> PII;

    const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 9901;

    int quickmod(int a, int b)
    {
    a %= MOD;
    int res = 1;
    while (b)
    {
    if (b & 1)
    res = res * a % MOD;
    a = a * a % MOD;
    b = b >> 1;
    }
    return res % MOD;
    }

    signed main()
    {
    IOS;
    int a, b;
    cin >> a >> b;
    if (!a)
    {
    cout << 0;
    return 0;
    }
    // 质因子分解
    unordered_map<int, int> mp;
    for (int i = 2; i <= a / i; ++i)
    {
    while (a % i == 0)
    {
    mp[i]++;
    a /= i;
    }
    }
    if (a > 1)
    mp[a]++;
    int ans = 1;

    auto f = [&](int p, int n) {
    if ((p - 1) % MOD == 0)
    return n + 1;
    int pp = quickmod(p, n + 1);
    int ny = quickmod(p - 1, MOD - 2);
    return (pp - 1 + MOD) * ny % MOD;
    };

    for (auto [x, cnt] : mp)
    {
    ans = ans * f(x, cnt * b) % MOD;
    }
    cout << ans;
    return 0;
    }


    做法二

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    /*
    * @Author: NEFU AB-IN
    * @Date: 2023-02-18 12:21:32
    * @FilePath: \Acwing\97\97.1.cpp
    * @LastEditTime: 2023-02-19 11:36:53
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #undef int

    #define SZ(X) ((int)(X).size())
    #define ALL(X) (X).begin(), (X).end()
    #define IOS \
    ios::sync_with_stdio(false); \
    cin.tie(nullptr); \
    cout.tie(nullptr)
    #define DEBUG(X) cout << #X << ": " << X << '\n'
    typedef pair<int, int> PII;

    const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 9901;

    int quickmod(int a, int b)
    {
    a %= MOD;
    int res = 1;
    while (b)
    {
    if (b & 1)
    res = res * a % MOD;
    a = a * a % MOD;
    b = b >> 1;
    }
    return res % MOD;
    }

    int sum(int p, int k)
    {
    if (k == 0)
    return 1;
    if (k % 2 == 0)
    return sum(p, k - 1) % MOD + quickmod(p, k) % MOD;
    return sum(p, k / 2) % MOD * (1 + quickmod(p, k / 2 + 1)) % MOD;
    }

    int main()
    {
    IOS;
    int a, b;
    cin >> a >> b;
    if (!a)
    {
    cout << 0;
    return 0;
    }
    // 质因子分解
    unordered_map<int, int> mp;
    for (int i = 2; i <= a / i; ++i)
    {
    while (a % i == 0)
    {
    mp[i]++;
    a /= i;
    }
    }
    if (a > 1)
    mp[a]++;
    int ans = 1;

    for (auto [x, cnt] : mp)
    {
    ans = ans * sum(x, cnt * b) % MOD;
    }
    cout << ans;
    return 0;
    }
使用搜索:谷歌必应百度