筛法的应用
因为直接算是不可能的,
我们可以处理出 \[ 1~\sqrt n \]的所有质数,然后筛掉\[L~R\] 区间内的所有质数
注意:
线性筛的时候,注意n与数组大小的关系,防止RE
与素数有关的一定要特判1的情况
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
const int MAXN = 75000;
ll l, r, prime[MAXN + 5], cnt;
bool f[MAXN + 5], fff[1000055];
void Euler_chk() {
f[1] = 1;
for(int i = 2 ; i < MAXN ; i++) {
if(!f[i]) {
prime[++cnt] = i;
}
for(int j = 1 ; i * prime[j] < MAXN; j++) {
f[i * prime[j]] = 1;
if(!(i % prime[j])) break;
}
}
}
int main() {
Euler_chk();
while(cin>>l>>r) {
memset(fff, 0, sizeof(fff));
for(int i = 1 ; i <=cnt && prime[i] <= r / 2 ; i++) {
if(!(l % prime[i]) && prime[i] < l) fff[0] = 1;
if(prime[i] < l) for(int j = floor((double)l / prime[i]) + 1; j <= floor((double)r / prime[i]) ; j++) {
fff[j * prime[i] - l] = 1;
}else for(int j = 2; j <= floor((double)r / prime[i]) ; j++) {
fff[j * prime[i] - l] = 1;
}
}
if(l == 1) fff[0] = 1;
//for(int i = 0 ; i <= (r - l) ; i++) printf("%d",fff[i]);
//printf("\n");
int ans1 = 0, ans2 = 0, l1 = 0, l2 = 0, r1 = 0, r2 = 0;
int head = 0, tail = 0;
while(fff[head] && head <= (r - l)) head++;
if(head > (r - l)) {printf("There are no adjacent primes.\n");continue;}
tail = head + 1;
while(fff[tail] && tail <= (r - l)) tail++;
if(tail > (r - l)) {printf("There are no adjacent primes.\n");continue;}
ans1 = ans2 = tail - head;
l1 = l2 = head + l;
r1 = r2 = tail + l;
while(head <= tail && tail <= (r - l)) {
//printf("%d %d\n", head + l, tail + l);
head = tail;tail++;
while(fff[tail] && tail <= (r - l)) tail++;
if(tail > (r - l)) break;
if((tail - head) > ans1) {
ans1 = tail - head;
l1 = head + l;
r1 = tail + l;
}
if((tail - head) < ans2) {
ans2 = tail - head;
l2 = head + l;
r2 = tail + l;
}
}
printf("%d,%d are closest, %d,%d are most distant.\n", l2, r2, l1, r1);
}
return 0;
}