1) 试除法求约数
原题链接:869. 试除法求约数 - AcWing题库
思路:与上面的试除法求质数很相似 a|b的意思是,b%a = 0
如果x|n 那么一定有(n/x)|n,所以,著需要求一个,另一个直接能得到
核心代码:
for(int i=1;i<=n/i;i++){
if(n%i==0){
a.push_back(i);
if(n/i!=i)a.push_back(n/i);
}
}
完整代码:
#include
#include
#include
using namespace std;
vector<int>a;
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
a.clear();
for(int i=1;i<=n/i;i++){
if(n%i==0){
a.push_back(i);
if(n/i!=i)a.push_back(n/i);
}
}
sort(a.begin(),a.end());
for(int x:a)cout<<x<<' ';
cout<<endl;
}
return 0;
}
2) 约数个数
原题链接:870. 约数个数 - AcWing题库
公式:假设一个数的质因数为 p1^a1 , p2^a2, p3^a3, … pk^ak
pi为质因数,ai为这个质因数的次数
那么约数个数 sum = (a1+1) * (a2+2) * … *(ak+k);
证明:严格推导有点麻烦,我在这就举个例子 假设
有一个数的质因数序列为 p1^1 , p2^2
那么 这个数的约数可能为 p1^0 * p2^0 , p1^0 * p2^1 , p1^0 * p2^2 , p1^1* p2^0 , p1^1 * p2^1 , p1^1* p2^2
相信看到这到这的小伙伴已经找到规律了 就是每一个质因数的次数+1然后相乘
至于为什么要+1 ,也很简答,因为是从0次方开始的
核心代码:
unordered_map<int,int>mp;
for(int i=2;i<=n/i;i++){
while(n%i==0){
n/=i;
mp[i]++;
}
}
if(n>1) mp[n]++;
}
int sum = 1;
for(auto x:mp)sum = sum%mod*(x.second+1);
完整代码
#include
#include
#define int long long
using namespace std;
int mod = 1e9+7;
unordered_map<int,int>mp;
signed main(){
int t;
cin>>t;
int j = 0;
while(t--){
int n;
cin>>n;
for(int i=2;i<=n/i;i++){
while(n%i==0){
n/=i;
mp[i]++;
}
}
if(n>1) mp[n]++;
}
int sum = 1;
for(auto x:mp)sum = sum%mod*(x.second+1);
cout<<sum%mod<<endl;
return 0;
}
3)约数和
原题链接:871. 约数之和 - AcWing题库
公式:假设一个数的质因数为 p1^a1 , p2^a2, p3^a3, … pk^ak
pi为质因数,ai为这个质因数的次数
那么约数和 sum = (p1^0 + p1^1+… p1^a1) * (p2^0 + p2^1 +…) * … *(pk^0 + pk^1+ …+pk^ak);
证明:由约数的个数公式推导而来,还是那个例子
有一个数的质因数序列为 p1^1 , p2^2
那么 这个数的约数可能为 p1^0 * p2^0 , p1^0 * p2^1 , p1^0 * p2^2 , p1^1* p2^0 , p1^1 * p2^1 , p1^1* p2^2
那么我们合并同类项发现等于 sum = p1^0 *(p2^0 + p2^1 + p2^2) + p1^1 *(p2^0 + p2^1 + p2^2) = (p1^0 + p1^1) * ( p2^0 + p2^1 + p2^2)
完整代码:
#include
#include
#define int long long
using namespace std;
int mod = 1e9+7;
unordered_map<int,int>mp;
signed main(){
int t;
cin>>t;
int j = 0;
while(t--){
int n;
cin>>n;
for(int i=2;i<=n/i;i++){
while(n%i==0){
n/=i;
mp[i]++;
}
}
if(n>1) mp[n]++;
}
int sum = 1;
for(auto x:mp){
int t=x.first+1;
for(int i=1;i<x.second;i++)t = t%mod*x.first%mod+1;
sum = sum%mod*t%mod;
}
cout<<sum%mod<<endl;
return 0;
}