Prime number distance -------------------------------------- Number theory (linear sieve + interval mapping)

Given two integers L and U, you need to find the two nearest prime numbers C1 and C2 (that is, C2-C1 is the smallest) in the closed interval [L, U], if there are other phases at the same distance For the adjacent prime number pairs, the first pair is output.

At the same time, you also need to find the two neighboring prime numbers D1 and D2 that are farthest away (ie, D1-D2 is the largest). If there are other neighboring prime pairs at the same distance, the first pair is output.

Input format
Enter two integers L and U per line, where the difference between L and U will not exceed 1000000.

Output format
For each L and U, output a result, the result occupies one line.

The result includes the nearest neighboring prime number pair and the farthest neighboring prime number pair. (Refer to the sample for the specific format)

If there are no prime number pairs between L and U, then "There are no adjacent primes." Is output.

Data range
1≤L <U≤231−1
Sample input:
2 17
14 17
Sample output:
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.

Analysis:
You cannot violently sift, because the range of n = 2e9 will definitely time out.
Assuming a composite number x
a factor n and another x / n,
then the factor n must be less than x / n.
According to this property, we can sift out the complex number in [L, R].
2e9 root number is about 50000

n = 50000 We run a linear screen. Find all the prime factors in [1.50000]. Then there is a part of a composite number decomposition in [1.50000].

For each prime number p in [1,50000], sieve out all multiples of p in [L, R] (at least 2 times)

Then the smallest multiple of p greater than or equal to L, p0 = (L + p-1) / p p;
because at least 2 times p0 = max (2
p, (L + p-1) / p * p)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+1000;
int prime[N],cnt;
bool st[N];
ll l,r;
void init(int n)
{
	memset(st,false,sizeof st);
	cnt=0;
	for(int i=2;i<=n;i++)
	{
		if(!st[i]) prime[++cnt]=i;
		for(int j=1;j<=cnt&&prime[j]<=n/i;j++)
		{
			st[prime[j]*i]=true;
			if(i%prime[j]==0) break;
		}
	}
}
int main()
{
	while(~scanf("%lld %lld",&l,&r))
	{
		init(50000);
		memset(st,false,sizeof st);
		for(int i=1;i<=cnt;i++)
		{
			ll p=prime[i];
			for(ll j=max(p*2,(l+p-1)/p*p);j<=r;j+=p) st[j-l]=true;
			
		}
		cnt=0;
		for(int i=0;i<=r-l;i++)
		{
			if(!st[i]&&(i+l)>=2) //1不是质数,所以必须从2开始
			{
				prime[++cnt]=i+l;
			}
		}
		if(cnt<2) puts("There are no adjacent primes.");
		else
		{
			int minp=1,maxp=1;
			for(int i=1;i<=cnt-1;i++)
			{
				int d=prime[i+1]-prime[i];
				if(d<prime[minp+1]-prime[minp]) minp=i;
				if(d>prime[maxp+1]-prime[maxp]) maxp=i;
			}
			printf("%d,%d are closest, %d,%d are most distant.\n",prime[minp],prime[minp+1],prime[maxp],prime[maxp+1]);
		}
	}
}
Published 572 original articles · praised 14 · 10,000+ views

Guess you like

Origin blog.csdn.net/qq_43690454/article/details/105385885