欧拉筛

这个狗日的欧拉筛真是慢到服气= =...

放一个uoj上1E的分解跑0.6s的欧拉筛.

#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<random>
#define pi 6000000
#define maxn 100000010
short low[maxn];
int pr[pi],prl;
inline int min(int a,int b){ return a<b?a:b; }
void sieve(int n=100000000,int i=6){
	pr[0]=2; pr[1]=3; pr[2]=5; prl=3;
	low[4]=2; low[6]=2; low[8]=2; low[9]=3;
	low[10]=2; low[12]=2; low[14]=2; low[15]=3;
	low[16]=2; low[25]=5;
	for(int _=2000,v;i<=_;++i){
		if(!(v=low[i])) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fket;
		low[i*3]=3; if(3==v) goto fket;
		low[i*5]=5; if(5==v) goto fket;
		for(int j=3,t;j<prl && (t=i*pr[j])<=n;++j){
			low[t]=pr[j];
			if(v==pr[j]) goto fket;
		} fket:;
	}
	for(int _=n/5,v;i<=_;++i){
		if(!(v=low[i])) pr[prl++]=i,v=i;
		low[i<<1]=2; if(!(i&1)) goto fk2;
		low[i*3]=3; if(3==v) goto fk2;
		low[i*5]=5; if(5==v) goto fk2;
		v=min(v,n/i);
		for(int j=3;pr[j]<=v && j<prl;++j) low[i*pr[j]]=pr[j];
		fk2:;
	}
	for(int _=n/3;i+8<=_;){
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fk1;
		low[i*3]=3; fk1:;
		++i;
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fkb;
		low[i*3]=3; fkb:;
		++i;
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fkc;
		low[i*3]=3; fkc:;
		++i;
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fkd;
		low[i*3]=3; fkd:;
		++i;
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fke;
		low[i*3]=3; fke:;
		++i;
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fkf;
		low[i*3]=3; fkf:;
		++i;
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fkg;
		low[i*3]=3; fkg:;
		++i;
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2; if(!(i&1)) goto fkh;
		low[i*3]=3; fkh:;
		++i;
	}
	for(int _=n/3;i<=_;++i){
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2;
		if(!(i&1)) goto fki;
		low[i*3]=3;
		fki:;
	}
	if(i&1){
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2;
		++i;
	}
	for(int _=n>>1;i+8<=_;){
		low[(i++)<<1]=2;
		if(!low[i]) pr[prl++]=i;
		low[(i++)<<1]=2;
		low[(i++)<<1]=2;
		if(!low[i]) pr[prl++]=i;
		low[(i++)<<1]=2;
		low[(i++)<<1]=2;
		if(!low[i]) pr[prl++]=i;
		low[(i++)<<1]=2;
		low[(i++)<<1]=2;
		if(!low[i]) pr[prl++]=i;
		low[(i++)<<1]=2;
	}
	for(int _=n>>1;i<=_;++i){
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2;
	}
	while(i%3 || i&1){
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2;
		++i;
	}
	for(int j=0;j<5;++j){
		if(!low[i]) pr[prl++]=i;
		low[i<<1]=2;
		++i;
	}
	for(;i+120<=n;){
		int a=i+2,b=i+6,c=i+8,d=i+12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		a+=12, b+=12, c+=12, d+=12;
		if(!low[a]) pr[prl++]=a;
		if(!low[b]) pr[prl++]=b;
		if(!low[c]) pr[prl++]=c;
		if(!low[d]) pr[prl++]=d;
		i=d;
	}
	for(;i+24<=n;){
		if(!low[i]) pr[prl++]=i; i+=2;
		if(!low[i]) pr[prl++]=i; i+=4;
		if(!low[i]) pr[prl++]=i; i+=2;
		if(!low[i]) pr[prl++]=i; i+=4;
		if(!low[i]) pr[prl++]=i; i+=2;
		if(!low[i]) pr[prl++]=i; i+=4;
		if(!low[i]) pr[prl++]=i; i+=2;
		if(!low[i]) pr[prl++]=i; i+=4;
	}
	for(;i<=n;++i) if(!low[i]) pr[prl++]=i;
}

和咸鱼有什么区别= =..

当然我们可以加些特技!(坑待填)

Upd.1

改了改,用了wheel sieve的一些技巧.

(GitHub) https://github.com/iamstupid/codeBase/blob/master/OI/wheelSieve.cpp

(UOJ) http://uoj.ac/submission/68564

(达到了primesieve的1/5速度,可喜可贺)

(其实主要瓶颈在RAM吞吐上...毕竟每个low是一个short优化不了..)

原文地址:https://www.cnblogs.com/tmzbot/p/5433122.html