オイラーとエリクセンふるいふるいです

1.エリクセン画面
思考:任意の合成数は、いくつかの要因の積として表すことができ、その後、我々は、各素数を見つけることができ、それが(この番号の代わりに、合成数である)彼の倍数がマークされているだろう。我々はマーク2から始めたので2は、最も小さい素数です。時間計算量は次のとおりO(N * LOGN)
次のようにコードです。

const int maxn=1e5+10;
bool flag[maxn];
int prime[maxn];
int pri_cnt=0;
void get_prime(int n){
	for(int i=2;i<=n;i++){
		if(!flag[i]){
			prime[++pri_cnt]=i;
			for(int j=i*i;j<=n;j+=i){
				flag[j]=1;
			}
		}
	}
}

  上記の場合はj=i*i上記の考えに従って、疑いの誰かであってもよいし、初期値がj等しくあってはならない2*i範囲ので、それi*(2~ i-1)2~i-1soから、時間外の雑草に行ったことがあるi * i。初め
2.オイラー画面
我々はすでにエリクセンふるいふるいから知っている:思考データの量が合成数のいくつかは、より多くの素因数がマークされます繰り返した、成長して、私たちは少し最適化をした場合でも、コアがマークされているが、我々は見つけることができます。私たちは、それぞれの合成数がマークされているようなユニークな合成数は、一度だけ、時間計算量がO(N)に低減されますで標識した首相と考えることができます。
コードは次のよう:

const int maxn=1e5+10;
int v[maxn],prime[maxn];//数组v记录每个数的最小质因子 
int pri_cnt=0;//pri_cnt记录质数的个数 
void prime_table(int n){
	for(int i=2;i<=n;i++){
		if(v[i]==0){//i是质数 
			v[i]=i;	
			prime[++pri_cnt]=i;
		}
		for(int j=1;j<=pri_cnt;j++){
			//如果(i*prime[j])有比prime[j]更小的因子,或者超出n的范围,停止循环
			if(prime[j]>v[i] || prime[j]>(n/i)) break;
			//prime[j]是合数i*prime[j]的最小因子 
			v[i*prime[j]]=prime[j];
		} 
	} 
}

  prime[j]>v[i]現在プライム示しprime[j]乗法因子よりはiエンゲージメントの数を表し、大きい最小素数i*prime[j]でなければならないi最小の素因数v[i]電流素数ではなく、選別prime[j];よう= 4×3 12:たとえば、選別i=4 prime[j]=3、12図2は、2フォー(の最小素因数である、選別されるべきであるv[4]=2)ので、ループの外ではなく、最大画面3に、選別。
  prime[j]>(n/i)それがされているprime[j]*i>nオーバーフローを防止するために分割することによって乗算することなく、意味する(ときに、データ時間大量の、INT破裂します)

公開された10元の記事 ウォン称賛7 ビュー158

おすすめ

転載: blog.csdn.net/qq_44204959/article/details/104763085