给定m,求1-m之间所有的素数
埃氏筛法
找到一个素数的时候,把它的倍数都打上标记
这样的话只要循环到一个没有标记的数那它就是素数了
void primes() { go(i,2,m) { if(fg[i])continue; go(j,i,m/i)fg[i*j]=1; prime[++ct]=i; } }
线性筛
发现在上面的埃氏筛法里,一个合数被打上标记的次数可能有多次,这里还可以优化
要确定一种一个合数只被打上一次标记的方法
最简单的就是用这个数的最小质因数来给它打上标记啊
void primes() { go(i,2,m) { if(!minp[i]){prime[++ct]=i;minp[i]=i;}//minp[i]是数i的最小质因数 go(j,1,ct) { if(prime[j]>minp[i]||prime[j]>m/i)break;//prime[j]大于了i的最小质因数 不能用prime[j]标记prime[j]*i //prime[j]*minp[i]>m minp[i*prime[j]]=prime[j]; } }