[模板] 区间筛素数

原理:一个数的倍数肯定不是素数

若给定子区间[fst, lst]

则必有区间内任意数最大的因子是sqrt(lst);

因此只需要将2 - sqrt(lst)中的所有质数的倍数从区间[fst, lst]中划掉即可

剩下的就是区间内的素数

注意两个情况

1. 第一次筛出的素数就在区间里 要特判

2. 将区间[fst, lst]映射入[0, lst - fst]

3.bitset优化


例题 https://www.acwing.com/problem/content/198/

代码:

/*
    Zeolim - An AC a day keeps the bug away
*/
 
//pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 10;
const ll MOD = 1e9 + 7;
 
vector <ll> getprime(ll n, ll m)
{
	vector <ll> pri;
	bitset <MAXN> used(0), rused(0);
	ll len = sqrt(m);
	for(int i = 2; i <= len; ++i)
	{
		if(!used[i])
		{
			ll x = i, y = max(x, x * (n / x));
 
			while(y <= m)
			{
				if(y - n >= 0 && y != x)
					rused[y - n] = true;
				y += x;
			}
			for(int j = 2 * i; j <= len; j += i)
    		{
    			used[j] = true;
    		}
		}
	}
	 
	for(int i = 0; i <= m - n; ++i)
	{
		if(i + n >= 2 && !rused[i])
			pri.push_back(i + n);
	}
	return pri;
}
 
int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);     cout.tie(0);
    //freopen("D://test.in", "r", stdin);
    //freopen("D://test.out", "w", stdout);
 
	ll n, m;
 
	while(scanf("%lld%lld", &n, &m) != EOF)
	{
		getprime(n, m);
	
		vector <ll> rpri = getprime(n, m);
	
		int cha = -1, pa = -1, pb = -1;
	
		int rcha = INF, rpa = -1, rpb = -1;
	
		for(int i = 1; i < rpri.size(); ++i)
		{
			int val = rpri[i] - rpri[i - 1];
			if(val > cha)
			{
				cha = val, pa = rpri[i - 1], pb = rpri[i];
			}
			if(val < rcha)
			{
				rcha = val, rpa = rpri[i - 1], rpb = rpri[i];
			}
		}
		
		if(cha > 0)
			printf("%d,%d are closest, %d,%d are most distant.\n", rpa, rpb, pa, pb);
		else
			printf("There are no adjacent primes.\n");
	}
 
	
 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Zeolim/article/details/89500952