约数之和 约数个数 最大公约数

约数公式

关于约数,有两个公式,一个是约数个数公式,一个是约数之和公式

约数个数

n个数相乘的因数个数,答案对 109+7 取模

公式

(1)N=p1n1p2n2pknk(2)=(n1+1)(n2+1)(nk+1)(3)d(4)d=p1m1p2m2pkmk,0mimi

想法

小学奥数题,指数加一再连乘

把一个数分解质因数,再把每一个质因数的指数加一乘起来

比如一个数N分解成P1n1×P2n2××Pknk 通过组合来理解
如果两项的ni不同,那么就会产生不同的因数
所以N的因数个数和指数ni的选法个数相等
对于Pi的指数ni,可以选择0,1,2,3i个,也就是i+1种选法
所以每个Pi的选法i+1乘起来就是总的选法,也就是N的因数个数

代码

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

using namespace std;
typedef long long LL;

const int mod = 1e9+7;

int main()
{
    int n;
    scanf("%d", &n);
    
    unordered_map<int, int> primes; // 用哈希表存,数组存不下
    
    while (n -- )
    {
        int x;
        scanf("%d", &x);
        // 分解质因数
        for(int i = 2; i <= x / i; i++)
        {
            while(x % i == 0)
            {
                x /= i;
                primes[i]++;
            }
        }
        if(x > 1) primes[x] ++;
    }
    
    LL res = 1; // 存答案
    
    for(auto t : primes) res = res * (t.second + 1) % mod; // 质数加一再连乘 记得模mod
    
    cout << res << endl;
    
    return 0;
}

约数之和

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

公式

(p10+p11++p1c1)××(pk0+pk1++pkck)

证明

证明:算术基本定理

一个数N只能被拆分为唯一的p1c1×p2c2××pkck
所以N的每个因数就是N分解质因数后因指数的每一种选法
看公式,在每个括号里面都是pi的一种选法,与另一些括号里的pi相乘,就是每一个因数,根据乘法分配律,上面的公式就是所有因数之和

代码

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

typedef long long LL; // long long类型
using namespace std;

const int mod = 1e9 + 7; // 模

int main()
{
    int n;
    scanf("%d", &n);
    unordered_map<int, int> primes; // 哈希表
    
    while (n -- )
    {
        int x;
        scanf("%d", &x);
        // 分解质因数
        for(int i = 2; i <= x / i; i++)
            while(x % i == 0) 
		x /= i, primes[i] ++;
        
        if(x > 1) primes[x] ++;
    }
    
    
    LL res = 1;
    for(auto t : primes) // 迭代器简单写法(auto C++ 11标准)
    {
        LL a = t.first, b = t.second;
        LL temp = 1;
        // 公式
        while(b -- )
            temp = (temp * a + 1) % mod;
        
        res = res * temp % mod;
    }
    
    cout << res << endl;
    
    return 0;
}

最大公约数

给定 n 对正整数 ai,bi,请你求出每对数的最大公约数。

想法

1.辗转相除
2. algorithm库__gcd()这是最快的

思路

两个数的gcd等于其中较小的数字和二者之间余数的gcd

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int gcd(int a, int b)  // 欧几里得算法
{
    return a % b ? gcd(b, a % b) : b;
    // return b ? gcd(b, a % b) : a;
}

int main()
{
    int n;
    scanf("%d", &n);
    while (n -- )
    {
        int a, b;
        scanf("%d%d", &a, &b);   
        
        cout << gcd(a, b) << endl;
        // cout << __gcd(a, b) << endl;
    }

    return 0;
}
posted @   MoyouSayuki  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
:name :name
点击右上角即可分享
微信分享提示