Sumdiv

在这里插入图片描述
都说用分治法来做
这里我写个数论的解法

首先对于给定的底数进行因式分解,底数的多少次幂只需要对因式分解后的结果进行相应的幂运算即可
然后利用因数和的公式进行求解
这里用的是等比数列求和公式,注意要将除法转化成乘逆元的形式
因为负数取模的结果依然的负数,所以要对这里的取模进行特殊处理

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 9901;
unordered_map<ll, ll> vis;
ll qmi(ll a, ll b, ll p)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
            res = res * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return res;
}
int main()
{
    ll a, k;
    cin >> a >> k;
    if (a == 0)
        cout << "0" << endl;
    else
    {
        ll b = a;
        for (ll i = 2; i <= b / i; i++)
        {
            while (b % i == 0)
            {
                b = b / i;
                vis[i]++;
            }
        }
        if (b > 1)
            vis[b]++;
        ll res = 1;
        for (auto i : vis)
        {
            ll p = i.first, a = i.second * k;
            ll t = ((1 - qmi(p, a + 1, MOD)) * qmi(1 - p, MOD - 2, MOD)) % MOD; //除法改成乘逆元的形式
            if (t < 0) //对取模进行处理,不得到负数
                t = MOD % t;
            res = res * t % MOD;
        }
        cout << res << endl;
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用C++实现上述思路的代码: ```cpp #include <iostream> #include <vector> using namespace std; const int mod = 1000000007; // 线性筛法计算欧拉函数的前缀和 void calculatePhi(vector<int>& phi, vector<int>& prime, vector<bool>& isPrime, int k) { phi[1] = 1; for (int i = 2; i <= k; i++) { if (isPrime[i]) { prime.push_back(i); phi[i] = i - 1; } for (int j = 0; j < prime.size() && i * prime[j] <= k; j++) { isPrime[i * prime[j]] = false; if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; } else { phi[i * prime[j]] = phi[i] * (prime[j] - 1); } } } // 计算前缀和 for (int i = 2; i <= k; i++) { phi[i] = (phi[i] + phi[i - 1]) % mod; } } // 计算⌊n/i⌋的前缀和 vector<int> calculateDivPrefixSum(int n, int k) { vector<int> sumDiv(k + 1, 0); for (int i = 1; i <= k; i++) { sumDiv[i] = (sumDiv[i - 1] + n / i) % mod; } return sumDiv; } int main() { int k; cin >> k; vector<int> phi(k + 1, 0); vector<int> prime; vector<bool> isPrime(k + 1, true); calculatePhi(phi, prime, isPrime, k); vector<int> sumDiv = calculateDivPrefixSum(k, k); int result = 0; for (int i = 1; i <= k; i++) { int factorCount = k / i; int temp = (sumDiv[factorCount] - sumDiv[i - 1] + mod) % mod; result = (result + phi[i] * temp) % mod; } cout << result << endl; return 0; } ``` 你可以将上述代码保存为一个.cpp文件,然后使用C++编译器进行编译和运行。输入k的值,即可得到最终结果。 希望对你有帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值