zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    【渗透测试】hydra使用小结
    Git/SQL/正则表达式的在线练习平台
    加密算法的前世今生
    Linux的进程、线程、文件描述符是什么
    一文看懂 session 和 cookie
    Linux 文件目录都是什么鬼?
    Linux shell 的实用小技巧
    关于 Linux shell 你必须知道的
    我用四个命令概括了 Git 的所有套路
    如何寻找最长回文子串
  • 原文地址:https://www.cnblogs.com/SwiftAC/p/12110786.html
Copyright © 2011-2022 走看看