POJ 2689 Prime Distance(区间素数筛)
题目大意
求一个区间内相差最小的一对相邻素数,和相差最大的一对相邻素数。
具体实现
注意越界。
代码
const int maxn = 2e6+10;
ll u[maxn], p[maxn], tmp[maxn], kase;
bool isp[maxn];
void pri() {
for (int i = 2; i<maxn; ++i) {
if (!u[i]) u[i] = p[++kase] = i;
for (int j = 1; i*p[j]<maxn; ++j) {
u[i*p[j]] = p[j];
if (!(i%p[j])) break;
}
}
}
int main(void) {
pri();
ll l, r;
while(~scanf("%lld%lld", &l, &r)) {
zero(isp);
for (int i = 1; 1LL*p[i]*p[i]<=r; ++i) //区间筛选
for (ll j = l/p[i]*p[i]; j<=r; j+=p[i])
if (j>p[i] && j>=l) isp[j-l] = true;
int tot = 0;
for (ll i = l; i<=r; ++i) //将素数存入一个数组中
if (!isp[i-l] && i!=1) tmp[tot++] = i;
ll maxx = -1, minn = INF;
P ans1 = P(0,0), ans2 = P(0,0);
for (int i = 1; i<tot; ++i) {
if (maxx < tmp[i]-tmp[i-1]) {
ans1 = P(tmp[i-1], tmp[i]);
maxx = tmp[i]-tmp[i-1];
}
if (minn > tmp[i]-tmp[i-1]) {
ans2 = P(tmp[i-1],tmp[i]);
minn = tmp[i]-tmp[i-1];
}
}
if (!ans1.first) printf("There are no adjacent primes.\n");
else printf("%d,%d are closest, %d,%d are most distant.\n", ans2.first,ans2.second,ans1.first,ans1.second);
}
return 0;
}