ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【模板】【线性筛】

2021-07-23 23:33:56  阅读:172  来源: 互联网

标签:ch 标记 int 合数 线性 质数 模板 getchar


【模板】【线性筛】

众所周知,即使是经过优化的埃氏筛,其复杂度依然为O(N log log N)

但我们需要一个O(N)的算法————线性筛

我们发现之所以埃氏筛会重复标记合数,是因为其没有确定该合数的唯一产生方式

线性筛的对策是————只用该合数的最小质因子标记该合数

于是,我们用一个v数组记录2~N中每个数的最小质因子

算法流程

  1. 枚举i从2~N;
  2. 若v[i]==0,即没有被标记过,说明i为质数,将i加入质数集合,并标记v[i]=i;
  3. 扫描不大于v[i]的每个质数p,令v[i*p]=p。

正确性

为什么所有合数在这个过程中都会被标记?因为任意一个合数i都一定能用它的最小质因子p0与一个小于i的整数i/p0的积表示
额……然后就证完了?(毕竟确实很显然

Code

#include<bits/stdc++.h>
using namespace std;

inline int read()
{
	register int x=0,w=1;
	register char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if(ch=='-'){ch=getchar();w=-1;	}
	while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();	}
	return x*w;
}
const int M=1e8+10;
int n,q,k,cnt;
int v[M],prime[M/8+100];
int main()
{
	n=read();
	q=read();
	for(int i=2;i<=n;++i)
	{
		if(v[i]==0){
			prime[++cnt]=i;
			v[i]=i;
		}
		for(int j=1;j<=cnt;++j)
		{
			if(prime[j]>v[i]||prime[j]*i>n) break;
			v[prime[j]*i]=prime[j];
		}
	}
	for(int i=1;i<=q;++i){
		k=read();
		printf("%d\n",prime[k]);
	}
	return 0;
} 

标签:ch,标记,int,合数,线性,质数,模板,getchar
来源: https://www.cnblogs.com/glq-Blog/p/15054168.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有