>Link
UVA 10140
ybtoj质数距离
>Description
给出若干个询问,询问
[
l
,
r
]
[l,r]
[l,r] 中相邻两个质数之间最大值和最小值
l
,
r
∈
[
1
,
2
31
−
1
]
,
r
−
l
≤
1
0
7
l,r\in [1,2^{31}-1],r-l\le 10^7
l,r∈[1,231−1],r−l≤107
>解题思路
考虑到一个合数拥有一个最小质数,这个质数肯定在 r \sqrt r r 里面,所以我们只要根据 r \sqrt r r 里的质数筛一遍 [ l , r ] [l,r] [l,r] 就行了
要开longlong,不然TLE!(我老是不开longlong
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 10000010
#define LL long long
#define inf 1 << 30
#define LL long long
using namespace std;
int cnt;
LL n, l, r, ans1, ans2, a1, a2, b1, b2, prime[N], last;
bool ok[N];
int main()
{
// freopen ("sample input.in", "r", stdin);
while (~scanf ("%lld%lld", &l, &r))
{
n = sqrt (r), cnt = 0;
for (LL i = 2; i <= n; i++) ok[i] = 0;
for (LL i = 2; i <= n; i++)
{
if (!ok[i]) prime[++cnt] = i;
for (LL j = 1; j <= cnt && i * prime[j] <= n; j++)
{
ok[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
for (LL i = 0; i <= r - l; i++) ok[i] = 0;
ans1 = inf, ans2 = 0, last = -1;
for (LL i = 1; i <= cnt; i++)
{
for (LL j = l / prime[i]; j * prime[i] <= r; j++)
{
if (j * prime[i] < l) continue;
if (j * prime[i] > r) break;
if (j != 1)
ok[j * prime[i] - l] = 1;
//if (j )
}
}
for (LL i = l; i <= r; i++)
if (!ok[i - l])
{
if (i == 1) continue;
if (last != -1)
{
if (i - last < ans1)
ans1 = i - last, a1 = last, a2 = i;
if (i - last > ans2)
ans2 = i - last, b1 = last, b2 = i;
}
last = i;
}
if (ans1 == inf) printf ("There are no adjacent primes.\n");
else printf ("%lld,%lld are closest, %lld,%lld are most distant.\n", a1, a2, b1, b2);
}
return 0;
}