-
约数
- 求一个数的所有约数
- 可以用vector存储所有约数但要判重和排序,也可以用set直接存储不用判重并且不用排序
vector<int> sc(int n)
{
vector<int>res;
for(int i=1;i<=n/i;i++)
{
if(n%i==0)
{
res.push_back(i);
if(i!=n/i)
res.push_back(n/i);
}
}
sort(res.begin(),res.end());
return res;
}
-------------------------------------------------------------
for(int i=1;i<=n/i;i++)
{
if(n%i==0)
s.insert(i),s.insert(n/i);
}
- 求一个数的约数个数
- 定理一:任何一个数可以表示为
- x=p1a1* p2a2*……*pnan
- 则其对应的约数个数是(a1+1) * (a2+1) * …… * (an+1)
- 因为p是质数,其约数形式也是和x形式相同,所以随着a的变化,其就代表一个约数,a的组合数就是约数个数,也就是乘法原理
- 比如24=23 * 31所以约数个数就是(指数可以为0)C41 * C21=8
- 求一个数的约数和
- 定理二:
- 对应的约数之和为:(p10+p11+……p1a1) * … * (pk0+pk1……+pkak)
- 例如24=(20+21+22+2^3) * (30+31)
- 展开式就是代表每一项约数相加也就是约数和
- 就是1+3+2+6+4+12+8+24=60
-
!对于以上的俩个定理基于分解质因数的计算,都需要用hash表来映射存储底数也就是hash的下标也是最小质因数的值,指数是hash值
- 上代码
#include<iostream>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int mod=1e9+7;
int main()
{
int t;cin>>t;
unordered_map<int,int>hash;
while(t--)
{
int x;cin>>x;
for(int i=2;i<=x/i;i++)
{
while(x%i==0)
{
x/=i;
hash[i]++;
}
}
if(x>1)hash[x]++;
}
LL res=1;
for(auto x:hash)res*=x.second+1,res%=mod;
cout<<res<<endl;
return 0;
}
#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 x;cin>>x;
for(int i=2;i<=x/i;i++)
{
while(x%i==0)
{
x/=i;
hash[i]++;
}
}
if(x>1)hash[x]++;
}
LL res=1;
for(auto x:hash)
{
int p=x.first,q=x.second;
LL t=1,ans=0;
q++;
while(q--)
{
ans=(t+ans)%mod;
t=t*p%mod;
}
res=res*ans%mod;
}
cout<<res<<endl;
return 0;
}