AcWing 866. 试除法判定质数
时间复杂度\(O(\sqrt{n})\)
\[d|n\implies\cfrac{n}{d}|n \]\[d\leq\cfrac{n}{d}\implies d^2\leq n\implies d\leq \sqrt{n} \]#include<iostream>
#include<algorithm>
using namespace std;
bool is_prime(int n)
{
if(n < 2) return false;
for(int i = 2; i <= n / i; i++)
if(n % i == 0)
return false;
return true;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int a;
scanf("%d", &a);
if(is_prime(a)) puts("Yes");
else puts("No");
}
return 0;
}
AcWing 867. 分解质因数
时间复杂度介于\(O(\log{n})\)和\(O(\sqrt{n})\)之间
#include<iostream>
#include<algorithm>
using namespace std;
void divide(int n)
{
for(int i = 2; i <= n / i; i++)
if(n % i == 0) //i一定是质数
{
int s = 0;
while(n % i == 0)
{
n /= i;
s++;
}
printf("%d %d\n", i, s);
}
if(n > 1) printf("%d %d\n", n, 1); //n中最多只包含一个大于sqrt(n)的质因子,可通过反证法证明
puts("");
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int a;
scanf("%d", &a);
divide(a);
}
return 0;
}
AcWing 868. 筛质数
对于一个大于2的正整数p,如果p没有被筛掉,那么说明p不是2到p-1中任何一个数的倍数,即2到p-1中没有一个数是p的约数。
朴素筛法的时间复杂度计算
\[\cfrac{n}{2} + \cfrac{n}{3} + \cdots + \cfrac{n}{n} = n(\cfrac{1}{2} + \cfrac{1}{3} + \cdots + \cfrac{1}{n}) \]\[\lim_{n \to \infty}(\cfrac{1}{2} + \cfrac{1}{3} + \cdots + \cfrac{1}{n}) = \ln n + C \]C为欧拉常数,约为0.577
\[n\ln n < n\log_{2}{n} \]时间复杂度可以记成\(O(n\log n)\)
埃氏筛法的时间复杂度计算
质数定理:1~n中有\(\cfrac{n}{\ln n}\)个质数
而真实的时间复杂度为\(O(n\log \log n)\)
线性筛法的原理
1.i % pj == 0
pj一定是i的最小质因子,pj一定是pj * i的最小质因子
2.i % pj != 0
pj一定小于i的所有质因子,pj也一定是pj * i的最小质因子
对于一个合数x,假设pj是x的最小质因子,当i枚举到x/pj的时候一定会被筛掉,所以任何一个合数都会被筛掉,并且只用最小质因子来筛,每个数只有一个最小质因子,所以每个数只会被筛一次,所以是线性的。
//朴素筛法
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1000010;
int primes[N], cnt;
bool st[N];
void get_primes(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i])
{
primes[cnt++] = i;
}
for(int j = i + i; j <= n; j += i) st[j] = true;
}
}
int main()
{
int n;
scanf("%d", &n);
get_primes(n);
printf("%d\n", cnt);
}
//由于只有质数的倍数才需要筛掉,所以可以将筛选的循环放到判断里面去
//埃氏筛法
void get_primes(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i])
{
primes[cnt++] = i;
for(int j = i + i; j <= n; j += i) st[j] = true;
}
}
}
//埃氏筛法是筛掉质数的倍数,但仍会重复计算,线性筛法中每个合数只会被其最小质因子筛掉,解决了重复计算的问题
//线性筛法
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,质数,cfrac,pj,include,复杂度,AcWing
From: https://www.cnblogs.com/YuukiAsuna/p/17112621.html