OnlyPersistVictory DayOne

A

質問の意味:
間隔が与えられた場合[L、R] [L、R][ L R ]、この区間で隣接する差が最小と最大の素数のペアを尋ねます。
データ範囲:1≤L<R≤2147483647、R −L≤10 6 1 \ leq L <R \ leq 2147483647、RL \ leq10 ^ 61L<R2 1 4 7 4 8 3 6 4 7 RL1 06

回答:

  • 1≤L<R≤21474836471\ leq L <R \ leq2147483647を検討してください1L<R2 1 4 7 4 8 3 6 4 7の場合、直接線形ふるいを実行してはなりません。
    しかし、あなたが知ることができるのはRRですR内のすべての合成数の素因数は、R \ sqrt {R}を超えませんR

  • 1 0 6 10 ^ 6の範囲を考慮してください1 06.より直感的なアイデアは、最初にR \ sqrt {R}を前処理することですR すべての素数を入力し、
    これらの素数を使用して区間[L、R] [L、R]を除外します[ L Rのすべての合成数]最後に、[L、R] [L、R]を取得できます[ L R ]のすべての素数は隣接して比較できます。

  • ふるい素数の操作を思い出してください。
    プライムプライム決定された各素数についてp r i m e、からi = 2×primei = 2 \ timesprime=2××p r i m eが始まり、iiiprimeプライムp r i m eが増加し始め、iiiがnn以下nおよびトラバースされたすべての番号は、合成数でマークされます。Ehrlichふるい法は、次のシリーズを通じて時間計算量を証明できます。O(nlog⁡log⁡n)O(n \ log \ log n)O nlo glo gn
    この質問は、2 ∗プライム2 *プライムからふるいの考えを渡すことができます2p r i m e[L、R] [L、R]から始まります[ L R ]の間のすべての番号は、合成数でマークされています。
    すべてのふるい位置が[L、R] [L、R]にあることを確認するため[ L R ]
    すべてiii的初始素最大((L +素数-1)/素数∗素数、2×素数)max((L +素数-1)/素数*素数、2 \回素数)m a x L+p r i m e1 / p r i m ep r i m e 2××p r i m e

  • この時点で、この質問に合格することができます。

#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;

typedef long long ll;

ll L, R;
const int N = 1e6 + 10;
int pri[N], cnt = 0;
bool st[N];
void xs(int n) {
    
    
	st[0] = st[1] = true;
	for(int i = 2; i <= n; ++i) {
    
    
		if(!st[i]) pri[++cnt] = i;
		for(int j = 1; j <= cnt && i <= n / pri[j]; ++j) {
    
    
			st[i * pri[j]] = true;
			if(i % pri[j] == 0) break;
		} 
	}	
}

int p[N], act;
int ST[N];
void solve() {
    
    
	act = 0;
	int r = sqrt(R);
	for(int j = 1; j <= cnt && pri[j] <= r; ++j) {
    
    
		ll c = (L + pri[j] - 1) / pri[j];
		while(c < 2) ++c;
		ll fir = c * pri[j];
		for(ll i = fir; i <= R; i += pri[j]) ST[i - L] = 1;
	}
	
	for(int i = 0; i <= R - L; ++i) {
    
    
		if(ST[i]) continue;
		if(i + L < N && st[i + L]) continue;
		p[++act] = i + L;
	}
	
	if(act < 2) puts("There are no adjacent primes.");
	else {
    
    
		int mx = 2, mn = 2;
		for(int i = 3; i <= act; ++i) {
    
    
			if(p[mx] - p[mx - 1] < p[i] - p[i - 1]) mx = i;
			if(p[mn] - p[mn - 1] > p[i] - p[i - 1]) mn = i;
		}
		printf("%d,%d are closest, %d,%d are most distant.\n", p[mn - 1], p[mn], p[mx - 1], p[mx]);
	}
	
	for(int i = 0; i <= R - L; ++i) ST[i] = 0;
}

int main()
{
    
    
	xs(N - 1);
	while(~scanf("%lld%lld", &L, &R)) solve();
	return 0;
}

おすすめ

転載: blog.csdn.net/weixin_43900869/article/details/115364828