AcWing 871. 约数之和

38 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情

AcWing 871. 约数之和

给定 n 个正整数 ai,请你输出这些数的乘积的约数之和,答案对 10^9+7 取模。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个整数 ai。

输出格式

输出一个整数,表示所给正整数的乘积的约数之和,答案需对 10^9+7 取模。

数据范围

1 ≤ n ≤ 100,
1 ≤ ai ≤ 2×10^9

输入样例:

3
2
6
8

输出样例:

252

思路

约数和定理

约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。在大学之前,"约数"一词所指的一般只限于正约数。约数和倍数都是二元关系的概念,不能孤立地说某个整数是约数或倍数。一个整数的约数是有限的。同时,它可以在特定情况下成为公约数。

约数推导

由算数基本定理可知,对于一个大于1的正整数N可以分解质因数 image.png

约数证明

image.png

image.png image.png

约数之和模板

如果 N = p1^c1 * p2^c2 * ... *pk^ck
约数之和: (p1^0 + p1^1 + ... + p1^c1) * ... * (pk^0 + pk^1 + ... + pk^ck)

ac代码

#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
unordered_map<int, int> primes;
int main(){
    int n;
    cin >> n;
    while(n--){
        int x;
        cin >> x;
        for(int i = 2;i <= x / i;i++){
            while(x % i == 0){
                x /= i;
                primes[i]++;
            }
        }
        if(x > 1) primes[x]++;
    }
    long long res = 1;
    for(auto p : primes){
        long long a = p.first,b = p.second,t = 1; //a是底数 b是指数
        while(b--){
            t = (t * a + 1) % mod; //从指数为0开始计算,任何数的0次方都为 1,所以直接+1,每次t * a等于进位
        }
        res = res * t % mod;
    }
    cout << res << endl;
    return 0;
}