约数之和

约数和定理

对于一个大于\(1\)正整数\(n\)可以分解质因数
                   \(n=p_1^{a_1}*p_2^{a_2}*p_3^{a_3}*\cdots*p_k^{a_k}\)
则由约数个数定理可知\(n\)的正约数有
                   \((a_1+1)*(a_2+1)*(a_3+1)*\cdots*(a_k+1)\)
那么\(n\)\((a_1+1)*(a_2+1)*(a_3+1)*\cdots*(a_k+1)\)个正约数的和为
                   \((p_1^0+p_1^1+p_1^2+\cdots+p_1^{a_1})(p_2^0+p_2^1+p_2^2+\cdots+p_2^{c_2})(p_k^0+p_k^1+p_k^2+\cdots+p_k^{c_k})=\prod_{i=1}^{k}(p_i^0+p_i^1+p_i^2+\cdots+p_i^{a_i})\)


例题

image


代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <unordered_map>

using namespace std;

typedef long long LL;
typedef unordered_map<int, int> unmap;

const int mod = 1e9 + 7;

unmap prime;

int main()
{
    int n;
    scanf("%d", &n);
    while (n -- )
    {
        int x;
        scanf("%d", &x);

        for (int i = 2; i <= x / i; i ++ )
            while (x % i == 0)
            {
                x /= i;
                prime[i] ++ ;
            }

        if (x > 1) prime[x] ++ ;
    }

    LL res = 1;

    for (unmap::iterator it = prime.begin(); it != prime.end(); it ++ )
    {
        LL sum = 1;
        LL cnt = 1;
        for (int i = 1; i <= it -> second; i ++ )
        {
            cnt = cnt * it -> first % mod;
            sum = (sum + cnt) % mod;
        }
        res = res * sum % mod;
    }

    printf("%lld", res);

    return 0;
}
posted @ 2021-04-07 02:13  筱翼深凉  阅读(177)  评论(0编辑  收藏  举报