约数

约数

算术基本定理:
image

试除法求约数 O(sqrt(n))

vector<int> get_devides(int x)
{
    vector<int> q;
    for(int i = 1 ; i <= x / i ; i ++)
    {
        if(x % i == 0)
        {
            q.push_back(i);
            if(x/i != i) q.push_back(x/i); // 这一步不要忘记
        }
    }
    sort(q.begin(),q.end());
    
    return q;
}

约数个数

题目链接: AcWing870

推导

摘自:https://www.acwing.com/solution/content/4969/

image

#include<iostream>
#include<unordered_map>

using namespace std ;

typedef long long LL ;
const int mod = 1e9 + 7;


int main()
{
    int n;
    cin >> n;
    
    unordered_map<int,int> hash;
    
    while(n --)
    {
        int a;
        cin >> a; // 把a用算术基本定理表示
        
        // 分解质因数
        for(int i = 2; i <= a/i ; i ++)
        {
            while(a % i == 0)
            {
                a /= i;
                hash[i] ++; // i的次数+1
            }
        }
        if(a > 1) hash[a] ++; 
    }
    
    LL res = 1;
    for(auto p : hash) res = res * (p.second + 1) % mod;
    
    cout << res;
    
    return 0;
}

约数之和

题目链接: AcWing871

image

#include<iostream>
#include<unordered_map>

using namespace std ;

const int mod = 1e9 + 7;
typedef long long LL;


int main()
{
    int n;
    cin >> n;
    
    unordered_map<int,int> hash;
    
    while(n --)
    {
        int a;
        cin >> a;
        
        for(int i = 2; i <= a/i ; i ++)
        {
            while(a % i == 0)
            {
                a /= i;
                hash[i] ++;
            }
        }
        if(a > 1) hash[a] ++;
    }
    
    LL res = 1;
    for(auto p : hash) 
    {
        LL a = p.first;
        LL b = p.second;
        LL t = 1;
        // 然后就用约数和公式求和即可 (p1^0+...+p1^a1)*...*(p1^k+...+p1^ak)
        while(b --) t = (t * a + 1) % mod;
        res = res * t % mod;
    }
    
    cout << res;
    
    return 0;
}
posted @ 2022-08-10 15:59  r涤生  阅读(46)  评论(0)    收藏  举报