约数与欧几里得算法

约数。。。

约数个数

我们先从一道简单的例题开始吧

需要知道的数学知识:

参考代码:

#include<iostream>
#include<unordered_map>
using namespace std;
const int MAGIC_NUMBER = 1e9 + 7;
int main(){
    int n, x;
    unordered_map<int, int> p; // p[j] = i 表示 j 这个质因数的次数为 i
    cin >> n;
    while(n--){
        cin >> x;
        int tmp = x;
        for(int i = 2; i <= tmp / i; i++){
            while(x % i == 0){
                x /= i;
                p[i]++;
            }
        }
        if(x > 1) p[x]++;
    } 
    long long res = 1;
    for(auto it : p){
        res = res * (it.second + 1) % MAGIC_NUMBER;
    }
    cout << res;
    return 0;
}

约数之和

依旧是一道例题:

这题也有相关数学知识:

这个公式要怎么证明呢,答案是展开就可以了,会发现就是所有约数组合之和

参考代码:

#include<iostream>
#include<unordered_map>
using namespace std;
const int MAGIC_NUMBER = 1e9 + 7;
int main(){
    // 质因数分解与上一问完全一样 
    int n, x;
    unordered_map<int, int> p; // p[j] = i 表示 j 这个质因数的次数为 i
    cin >> n;
    while(n--){
        cin >> x;
        int tmp = x;
        for(int i = 2; i <= tmp / i; i++){
            while(x % i == 0){
                x /= i;
                p[i]++;
            }
        }
        if(x > 1) p[x]++;
    } 

    long long res = 1;

    for(auto it : p){
        long long a = it.first;
        long long b = it.second; // 次数
        long long t = 1; // 本轮答案(也就是公式里面的一个括号) 
        while(b--){
            // 可能会对这个有疑惑
            // 可以模拟一下
            // 第一次:t = a + 1
            // 第二次:t = a^2 + a + 1
            // 看懂了吧 
            // 最高次最终会等于 b 
            t = (t * a + 1) % MAGIC_NUMBER;
        }
        res = res * t % MAGIC_NUMBER;
    }
    cout << res;
    return 0;
}

欧几里得算法

不错的图:

例题:

参考代码:

#include<iostream>
using namespace std;
int gcd(int a, int b){
    if(a % b == 0) return b;
    return gcd(b, a % b);
}
int main(){
    int n;
    cin >> n;
    while(n--){
        int a, b;
        cin >> a >> b;
        cout << gcd(a, b) << endl;
    }
    return 0;
}

实际上它还有一个更严谨的证明: