P3383 【模板】线性筛素数

线性筛法求质数

做法

  1. 用数组 (v) 来存储每个数的最小质因子

  2. 枚举2~n之间的数

  3. (v[i] == i) 则该数为质数,将其保存

  4. 穷举2~(v[i])的质数 (p) (不包含(v[i])),则(v[i*q]) = (q)

    1. 因为 (p) 小于(v[i]), 所以合数 (v[i*p]) 的最小质因子是 (p)

推论

  1. 从头往后挨个枚举,只要满足(v[i] = i),就加入prime[]

  2. 并把对应的(v[i*q](qle v[i]))更新,从而达到类似DP的动态类取数问题

  3. (prime) 数组存储 (n) 中的质数,这样就可以打印出每一个质数啦

  4. 时间复杂度 (O(n))

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;

const int manx=1e8+10;
const int mamx = 1e6 + 11;
const int B = 1e6 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;

inline int read() {
  char c = getchar(); int x = 0, f = 1;
  for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
  for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
  return x * f;
}
int v[manx],prime[manx],m;
void primes(int n){
	memset(v,0,sizeof(v));
	m = 0;
	for(int i = 2;i <= n; i++){
		if(v[i] == 0){
			v[i] = i;
			prime[++m] = i;
		}
		for(int j = 1;j <= m; j++){
			if(prime[j] > v[i] || prime[j] >n/i)break;//i有比prime[j]更小的因子,或者超出n的范围,则跳出循环 
			v[i*prime[j]] = prime[j];
		}
	}
	//for(int i = 1;i <= m ;i++)cout<<prime[i]<<endl;
	sort(prime + 1,prime + 1 + m);
}
int main(){
	int n =  read(),q = read();
	primes(n);
	for(int i = 1; i <= q; i++)
	{
		int x = read();
		//cout<<prime[x]<<endl;
	}
	return 0;
}


原文地址:https://www.cnblogs.com/lToZvTe/p/13933579.html