分解质因数
一个个枚举可以约的质数,记住最后的x如果大于1,那么还要再加上这个数
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N =1e5+5;
int n;
struct node{
int x,mi;
}a[N];
int idx=0;
void cal(int x){
for(int i=2;i*i<=x;i++){
if(x%i==0){
a[++idx].x=i;
while(x%i==0){
x/=i;
a[idx].mi++;
}
}
}
if(x>1){
a[++idx].x=x;
a[idx].mi=1;
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
memset(a,0,sizeof(a));
idx=0;
cal(x);
for(int i=1;i<=idx;i++){
cout<<a[i].x<<" "<<a[i].mi<<"\n";
}
cout<<"\n";
}
return 0;
}
筛质数
要求1到n中所有的质数,可以一个个枚举,并把这个数的倍数都删掉(用vis数组记录),因为倍数肯定不是质数。
#include <bits/stdc++.h>
using namespace std;
const int N =1e6+5;
int vis[N],a[N];
int n;
int idx=0;
void cal(int x){
for(int i=2;i<=x;i++){
if(!vis[i]){
a[++idx]=i;
for(int j=i;j<=x;j+=i){
vis[j]=1;
}
}
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
cal(n);
cout<<idx<<"\n";
return 0;
}
约数个数
将一个数分解成(p1^x1+p2^x2+....)的形式,其中p为质数,x为质数出现的次数,例如12这个数,可以把它分解成2个2,1个3,那么2可以选0~2个,3可以选0~1个,那么总共选的方法就是两者的乘积,记住枚举结束的时候不要忘了判断x>1.
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9+7;
int n;
unordered_map<int,int>mp;
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
for(int j=2;j*j<=x;j++){
while(x%j==0){
mp[j]++;
x/=j;
}
}
if(x>1)mp[x]++;
}
int ans=1;
for(auto t:mp){
ans=(ans*(t.second+1))%mod;
}
cout<<ans<<"\n";
return 0;
}
约数之和
基本思想:
如果n=p1^x1 * p2^x2 * p3^x3 ....
那么约数之和为
ans=(p1^0 + p1^1 + p1^2 + p1^3...+p1^x1)*(p2^0 + p2^1 + ... + p2^x2)*...
(每个括号选一个数,乘其他括号的数,因式分解)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9+7;
int n;
unordered_map<int,int>mp;
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
for(int j=2;j*j<=x;j++){
while(x%j==0){
mp[j]++;
x/=j;
}
}
if(x>1)mp[x]++;
}
int ans=1;
for(auto t:mp){
int a=t.first,b=t.second;
int k=1;
while(b--)k=(k*a+1)%mod;
ans=(ans*k)%mod;
}
cout<<ans<<"\n";
return 0;
}