• POJ1845 Sumdiv


    原题面:https://vjudge.net/problem/POJ-1845

    题目大意:求pow(A,B)的所有约数之和mod9901(1<=A,B<=5e7)。

    输入描述:一行两个正整数A(1<=A<=5e7),B(1<=B<=5e7)。

    输出描述:输出pow(A,B)所有约数之和mod9901。

    样例输入:

    2 3

    样例输出:

    15

    分析:把A分解质因数可得A=pow(p1,c1)pow(p2,c2)...pow(pn,cn)。故pow(A,B)的所有约数之和为(1+p1+pow(p1,2)+...+pow(p1,c1))(1+p2+pow(p2,2)+...+pow(p2,c2))...(1+pn+pow(pn,2)+...pow(pn,cn))。可以看出每个部分都是一个等比数列,运用等比数列求和公式即可求出每部分的值,最后相乘取模即为答案。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=40;
    const ll mod=9901;
    ll p[maxn],c[maxn],m;
    void divide(int n) {
        m = 0;
        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) {
                p[++m] = i;
                c[m] = 0;
                while (n % i == 0) n /= i, c[m]++;
            }
        }
        if (n > 1) p[++m] = n, c[m] = 1;
    }
    ll power(ll a,ll b) {
        ll ret = 1;
        while (b) {
            if (b & 1)
                ret = (ret * a) % mod;
            a = (a * a) % mod;
            b >>= 1;
        }
        return ret;
    }
    ll inv(ll a) {
        return power(a, mod - 2);
    }
    int main() {
        ll a, b;
        cin >> a >> b;
        divide(a);
        ll ret = 1;
        for (int k = 1; k <= m; k++) {
            if ((p[k] - 1 + mod) % mod == 0) {
                ret = (ret * ((b * c[k] + 1) % mod)) % mod;
                continue;
            }
            ret = (ret * (power(p[k], (ll) b * c[k] + 1) - 1 + mod) % mod) * inv(p[k] - 1) % mod;
        }
        cout << ret << endl;
        return 0;
    }
  • 相关阅读:
    linux安装nginx
    git配置多个SSH密钥
    webpack加载器安装node-sass失败的解决方法
    Vue-cli webpack打包之后index.html缺少引号的问题
    算法:一个数组中所有元素的最小公倍数
    JS 实现一个睡眠函数sleep
    剑指offer 牛客67道题集合
    剑指offer
    剑指offer
    剑指offer
  • 原文地址:https://www.cnblogs.com/SwiftAC/p/12110786.html
Copyright © 2020-2023  润新知