质数
大于2的数只包含1和它本身两个约数的数是质数。
判断质数
- 1、最朴素做法——试除法
bool is_prime(int x){
for(int i=2;i<n;i++)
if(x%i==0) return false;
return true;
}
//时间复杂度是O(n)
- 2、优化到sqrt(n)
我们可以发现,如果一个数可以整除d则也可以整除n/d,所以可以进行优化
bool is_prime(int x){
for(int i=2;i<=x/i;i++){
if(x%i==0)return false;
}
return true;
}
- 3、分解质因数——试除法
void get_prime(int n){
for(int i=2;i<=n/i;i++){
int s = 0;
while(n%i==0){//每次都把质因数÷干净了,所以不会有合数了。
s++;
n/=i;
}
if(s)printf("%d %d\n",i,s);
}
if(n>1)printf("%d 1\n",n);
}
- 4、筛质数
1.朴素筛法:枚举2-n,将每个质数的倍数都筛掉
质数定理:1-n中有n/lnn个质数,所以时间复杂度约为O(n)
2.线性筛法void s_prine(int n){ int cnt = 0,primes[N]; bool st[N]; for(int i=2;i<=n;i++){ if(!st[i]){ primes[cnt++]=i; for(int j=i;j<=n;j+=i)st[j] = true; } ) }
void s_primes(int n){ int primes[N],cnt = 0; bool st[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;//保证primes[j]一定是i的最小质因子 } } }
约数
- 1、试除法求所有约数
vector<int> get_ys(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);
}
}
return res;
}
- 2、约数个数
将n分解质因数,记录每个质因数分幂次,则约数个数是所有每次加1的乘积。
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
unordered_map<int,int>primes;
void get_gcd(int n){
for(int i=2;i<=n/i;i++){
while(n%i==0){
primes[i]++;
n/=i;
}
}
if(n>1)primes[n]++;
}
int main()
{
int n,a;
scanf("%d",&n);
while(n--){
scanf("%d",&a);
get_gcd(a);
}
long long res = 1;
for(auto t : primes)res = (res*(t.second+1)%mod)%mod;
printf("%d\n",res);
return 0;
}
- 3、约数之和
约数之和是所有质因数的0次幂到最高次幂之和再相乘。
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
unordered_map<int,int>primes;
void get_gcd(int n){
for(int i=2;i<=n/i;i++){
while(n%i==0){
primes[i]++;
n /= i;
}
}
if(n>1)primes[n]++;
}
int main()
{
int n,a;
scanf("%d",&n);
while(n--){
scanf("%d",&a);
get_gcd(a);
}
long long res = 1;
for(auto t : primes){
int p = t.first,cnt = t.second;
long long tp = 1;
for(int i=0;i<cnt;i++){
tp = (tp*p+1)%mod;
}
res = (res*tp)%mod;
}
printf("%lld",res);
return 0;
}
- 4、最大公约数
#include<bits/stdc++.h>
using namespace std;
int n,a,b;
int gcd(int a,int b){
while(a%b){
int t = a;
a = b;
b = t%b;
}
return b;
}
int main()
{
scanf("%d",&n);
while(n--){
scanf("%d%d",&a,&b);
printf("%d\n",gcd(a,b));
}
return 0;
}