蓝桥杯ACwing习题

https://www.acwing.com/problem/content/description/99/

// 举个例子,180 = 2^2 ∗ 3^2 ∗ 5^1
// 约数个数:(2+1)(2+1)(1+1) = 18
// 约数和:(1+2+4)(1+3+9)(1+5)=546
// 将后面的 (p1 ^ 0 + ... p1 ^ a1 / 2) 可以表示为 sum(p1 , k) 函数 

// n 可以写为 p1a1 + p2a2 +p3a3 + p4a4 + .... pnan;

// 约数个数
//  (1 + a1)(1 + a2)(1 + a3)(1 + an); 

// 约数之和

// (1 + p1 ^ 1 + p1 ^ 2 + ..... + p1 ^ k) + (1 + p2^1 + p2^3 + ... p2^k) + .. 每一项都是这么写的
// 单独讨论每一项 相乘就可以了
// 1 .. 若 k 是偶数的话 
// 可以写为(1 + p1 ^ 2 + p1 ^ 3 + .... p1 ^ k)
// 从中间拆开 (1 + p1 ^ 1 + p1 ^ 2 + .. p1 ^ k / 2) + (p1 ^ (k / 2 + 1) + .... + p1 ^ k)
// 后一项提出 p1 ^ ak / 2 + 1 ==> p1 ^ k / 2 * (1 + p1 ^ 1 + p1 ^ 2 + ....p1 ^ k / 2);
// 合并 1 式 2 式 可得 (1 + p1 ^ k / 2) * sum(p , k / 2);

// 2  .. 如果是k奇数的话
// 将第最后一项单独提出来 (p1 , k) * (p1 ^ 2 + p1 ^ 3 + ... p1 ^ k)
// 每一项往前错一位 , 那么k 就变为 k - 1 这时候是需要 (p1 ^ k) * sum(p , k - 1) 就可以了

#include
#include
#include

using namespace std;

const int mod = 9901;
typedef long long ll;

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

int sum(int a ,int b)
{
    if(b == 1) return 1;
    if(b % 2 == 0) return (1 + qmi(a , b / 2, mod)) * sum(a , b / 2) % mod;
    return (qmi(a , b - 1, mod) + sum(a , b - 1))% mod;
}

int main()
{
    int a , b;
    cin >> a >> b;
    
    int res = 1;
    for (int i = 2 ; i <= a / i ; i ++)
        if(a % i == 0)
        {
            int s = 0;
            while(a % i == 0)
            {
                s ++;
                a /= i;
            }
            res = res * sum(i , b * s + 1) % mod; 
        }
    
    if(a > 1) res = res * sum(a , b + 1) % mod;
    if (a == 0) res = 0;
    
    cout <     
    return 0;
}

你可能感兴趣的:(蓝桥杯,算法,职场和发展)