质数
质数的判定
试除法 时间复杂度:O(sqrt(n))
注意: 1.初始算法复杂度位O(n*n)
2.不推荐sqrt(n),因为此处sqrt的运算很慢
3.i*i不推荐,因为容易溢出
#include <iostream>
#include <algorithm>
using namespace std;
bool judge(int x)
{
if(x<2) return false;
for(int i=2;i<=x/i;i++)
{
if(x%i==0){
return false;
}
}
return true;
}
int main(){
int n;
cin>>n;
while(n--)
{
int m;
cin>>m;
if(judge(m)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
分解质因数
时间复杂度:介于log2 n到sqrt(n)之间。即x为2的n次方为最优。
#include <algorithm>
#include <iostream>
using namespace std;
int solve (int x)
{
for(int i=2;i<=x/i;i++)
{
int cnt=0;
if(x%i==0)
{
while(x%i==0)
{
x=x/i;
cnt++;
}
cout<<i<<" "<<cnt<<endl;
}
}
if(x>1) cout<<x<<" "<<1<<endl;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int x;
cin>>x;
solve(x);
cout<<endl;
}
return 0;
}
筛质数
普通筛法
埃氏筛法(10的六次方与线性筛法相同):
线性筛法(10的七次方最快,常用):把每一个合数用质因数筛掉
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000010;
int cnt = 0, n;
int primes[N];
bool st[N];
void get_primes (int n)
{
for (int i = 2; i <= n; i ++ )
{
if(!st[i]) primes[cnt++]=i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
int main()
{
cin >> n;
get_primes(n);
cout << cnt;
return 0;
}
约数
试除法求约数
时间复杂度 O(sqrt(n))yue
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector <int> get_divisors(int x)
{
vector<int> res;
for(int i=1;i<=x/i;i++)
{
if(x%i==0)
{
res.push_back(i);
if(i!=x/i) res.push_back(x/i);
}
}
sort(res.begin(),res.end());
return res;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int m;
cin>>m;
auto res=get_divisors(m);
for(auto t : res) cout<<t<<" ";
cout<<endl;
}
return 0;
}
约数的个数
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int mod=1e9+7;
typedef long long LL;
int main()
{
unordered_map <int,int> maps;
int n;
LL res=1;
cin>>n;
while(n--)
{
int m;
cin>>m;
for(int i=2;i<=m/i;i++)
{
while(m%i==0){
m=m/i;
maps[i]++;
}
}
if(m>1) maps[m]++;
}
for(auto p:maps) res=res*(p.second+1)%mod;
cout<<res;
return 0;
}
约数之和
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
const int mod=1e9+7;
typedef long long LL;
int main()
{
int n;
LL res=1;
unordered_map <int,int> hash;
cin>>n;
while(n--)
{
int m;
cin>>m;
for(int i=2;i<=m/i;i++)
{
while(m%i==0)
{
m=m/i;
hash[i]++;
}
}
if(m>1) hash[m]++;
}
for(auto p:hash)
{
LL a=p.first,b=p.second,l=1;
while(b--) l=(l*a+1)%mod;
res=res*l%mod;
}
cout<<res;
return 0;
}
求最大公约数
欧几里得算法(辗转相除法)
#include <algorithm>
#include <iostream>
using namespace std;
int get(int a,int b)
{
return b?get(b,a%b):a;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
cout<<get(a,b)<<endl;
}
return 0;
}