POJ2689-初等数论区间素数筛模板

题解见算法竞赛p134

技巧:

这个题l和r可能会很大,就不能用数组标记l-r内的素数,所以要加个偏移量,用l当作偏移量,则数组大小小于1e6的f[0,u-l],即可标记。

接着枚举区间中所有的相邻素数对即可。

由于1不是素数,所以对1要进行特别处理

这种处理的方式是从另一个dalao那里学来的

dalao博客:https://blog.csdn.net/a601025382s/article/details/12111297

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
typedef double db;
const int INF = 1e9;
const int maxn = 5e4+10;
const int maxm = 1e6 + 10;
int n,t, s;
int vis[maxn];
int prime[maxn];
void Eratosthenes(int n)
{
	t = 0;
	memset(vis, 0, sizeof(vis));
	for (int i = 2; i <= n; i++)
	{
		if (!vis[i])
			for (int j = i*i; j < maxn; j+=i) {
				vis[j] = 1;
			}
	}
	for (int i = 2; i < maxn; i++)if (!vis[i])prime[++t] = i;
}
int primes(int n)//O(N)
{
	memset(vis, 0, sizeof(vis));//最小质因子
	int m = 0;//质数数量
	for (int i = 2; i <= n; i++)
	{
		if (vis[i] == 0)
		{
			vis[i] = i;
			prime[++m] = i;
		}//i是质数
		for (int j = 1; j <= m; j++)
		{
			//i有比prime[j]更小的质因子,或者超出n的范围,停止循环.
			if (prime[j] > i || prime[j] > n / i)break;
			//prime[j]是合数i*prime[j]的最小质因数
			vis[prime[j] * i] = prime[j];
		}
	}
	return m;
}
//质因数分解
int v[maxm];
int main()
{
	int l, r;
	int m = sqrt(maxn+0.5);
	Eratosthenes(m);
	while (cin>>l>>r)
	{
		if (l == 1)l = 2;
		memset(v,0,sizeof(v));
		int x = sqrt(r);
		int num = 0;
		
		int k = 0;
		for (int i = 1; i <= t; i++)
		{
			int a =(l-1) / prime[i]+1;
			int b = r / prime[i];
			for (int j = a; j <= b; j++)
			{
				if (j > 1)
					v[prime[i] * j - l] = 1;
			}
		} 
		int mindis = INF;
		int maxdis = -1;
		int p=-1;
		int x1, x2, y1, y2;
		for (int i = 0; i <= r - l; i++)
		{
			if (v[i] == 0)
			{
				if (p == -1) {
					p = i;
					continue;
				}
				if (maxdis < i - p) {
					maxdis = i - p;
					x1 = p + l;
					y1 = i + l;
				}
				if (mindis > i - p) {
					mindis = i - p;
					x2 = p + l;
					y2 = i + l;
				}
				p = i;
			}
		}
		if (maxdis == -1)cout << "There are no adjacent primes." << endl;
		else cout << x2 << "," << y2 << " are closest, " << x1 << "," << y1 << " are most distant." << endl;
		
	}
}

猜你喜欢

转载自blog.csdn.net/qq_17175221/article/details/81632732