约数个数 和 约数之和

约数个数和约数之和

约数个数

一个数a的约数个数

​ a = p1a1 x p2a2 x p3a3 ... pkak

p1 p2 p3 ... pk 都是a中的质因数,a1 a2 a3 就是其中的p1 p2 p3 的个数。

所以约数个数为一个排列组合

可以在 p1 中选择 0 ~ a1 任意个数,

​ 在 p2 中选择 0 ~ a2 任意个数,

​ 在 p3 中选择 0 ~ a3 任意个数,然后他们的乘积,就是a 的约数

所以约数的个数 = (a1+1)x(a2+1)x (a3+1)... x(ak+1)

代码:

#include <iostream>
#include <map>//unordered_map会快很多,因为它的插入是O(1)的时间复杂度
using namespace std;
typedef long long ll;
map<int,ll> mp;
const ll mod = 1e9+7;
int main(){ 
    int n;
    cin>>n;
    int x;
    for(int i=0;i<n;i++){
        cin>>x;
        for(int j=2;j*j<=x;j++){
            int num=0;
            while(x%j==0){
                x/=j;
                num++;  
            }
            mp[j]+=num;
        }
        if(x>1) mp[x]++;
    }
    ll ans=1;
    for(auto it=mp.begin();it!=mp.end();it++){
        ans=(ans*(1+it->second))%mod;
    }
    cout<<ans;
    return 0;
}

约数之和

同理

​ a = p1a1 x p2a2 x p3a3 ... pkak

所以a的约数为

p10 x p20 ... x pk0 +

p10 x p20 ... x pk1

...

所以约数之和 = (p10 +p11+...p1a1)x (p20 +p21+...p2a2)... (pk0 +pk1+...pkak

相当于从每个括号里选一个数

ac代码:

#include <iostream>
#include <unordered_map>
using namespace std;
typedef long long ll;
unordered_map<int,ll> mp;
const ll mod = 1e9+7;
int main(){ 
	int n;
	cin>>n;
	int x;
	for(int i=0;i<n;i++){
		cin>>x;
		for(int j=2;j*j<=x;j++){
			int num=0;
			while(x%j==0){
				x/=j;
				num++;	
			}
			mp[j]+=num;
		}
		if(x>1) mp[x]++;
	}
	ll ans=1;
	for(auto it=mp.begin();it!=mp.end();it++){
		ll p=it->first,a=it->second;
		ll t=1;
		while(a--)
	    	t=(t*p+1)%mod;
	    ans=(ans*t)%mod;
	}
	cout<<ans;
	return 0;
}
原文地址:https://www.cnblogs.com/AC673523745/p/14329618.html