【欧拉筛】模板

学习了一波欧拉筛 希望能记住模板进行应用
https://blog.csdn.net/qq_39763472/article/details/82428602
借鉴了这片博客 再加上一些自己的想法

#include <iostream>
using namespace std;
const int maxn=1e3;
int a[maxn],vis[maxn];
int main(){
	//用a[0]储存质数的个数 
	for(int i=2;i<maxn;i++){
		cout<<"i="<<i<<endl;
		//如果未被标记过即为质数,将质数一个个存到数组里 
		if(!vis[i]) a[++a[0]]=i;
		//枚举 遍历数组a[]里已经存在的每个质数 将这些质数的i倍标记 
		for(int j=1;j<=a[0]&&i*a[j]<=maxn;j++){
			cout<<"  j = "<<j<<" a["<<j<<"]"<<" = "<<a[j]<<" i*a[j] = "<<i*a[j]<<endl;
			vis[i*a[j]]=1;
			//精髓的一步 
			//一直往后枚举 当i%a[j]==0时 此时i是a[j]的倍数
			//即 i=a[j]*k,如果继续枚举下去,当a[?]时 i*a[?]位置就被标记了 
			//即a[j]*k*a[?]这个位置被标记了,而之后i的for循环里 i=k*a[?]时
			//这个位置还是会被重复标记 
			//而 i%a[j]==0 就break 确保了a[j]一定是i的最小质因子 
			if(i%a[j]==0) break;
		}
	}
	return 0;
}

用图说话更清楚些:


这是把关键那句话注释之后的显示
可以看到 当i=4,a[2]=3时,此时vis[12]被标记了
而当 i=6,a[1]=2时,vis[12]又再次被标记

加了精华之后 就舒服了
只有 当i=6时 vis[12]会被标记
在这里插入图片描述
这是别的都删去了的代码 还挺美的

#include <iostream>
using namespace std;
const int maxn=1e3;
int a[maxn],vis[maxn];
int main(){
	for(int i=2;i<maxn;i++){
		cout<<"i="<<i<<endl;
		if(!vis[i]) a[++a[0]]=i;
		for(int j=1;j<=a[0]&&i*a[j]<=maxn;j++){
			vis[i*a[j]]=1;
			if(i%a[j]==0) break;
		}
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值