【POJ 2689】Prime Distance(素数筛法)

题目链接

【POJ 2689】Prime Distance


题解

题目的关键在于如何求出 l r 之间所有的素数。

性质:如果一个数 n 是合数,则它一定有一个 n 的素因子。
思路:先筛出 2 r 的所有素数 p i ,在一一标记 l r 中所有 p i 的倍数。

时间复杂度

O ( q p r r l p )

= O ( q ( r log log r + ( r l ) log log r ) )


代码

#include <cstdio>
#define isp(i) isp[i - l]
const int maxn = 50005;
const int maxm = 1000005;
typedef unsigned int ui;
bool vis[maxn], isp[maxm];
ui l, r, c, p[maxn];
ui lst, l0, l1, r0, r1;
int main() {
    for (ui i = 2; i < maxn; i++) {
        if (!vis[i]) {
            p[++c] = i;
            for (int j = i + i; j < maxn; j += i) {
                vis[j] = 1;
            }
        }
    }
    while (~scanf("%u %u", &l, &r) && l && r) {
        for (ui i = l; i <= r; i++) {
            if (i != 1) {
                isp(i) = 1;
            } else {
                isp(i) = 0;
            }
        }
        for (ui i = 1; i <= c; i++) {
            ui lb = (l + p[i] - 1) / p[i], rb = r / p[i];
            for (ui j = lb; j <= rb; j++) {
                if (j > 1) {
                    isp(j * p[i]) = 0;
                }
            }
        }
        lst = l0 = l1 = r0 = r1 = 0;
        for (ui i = l; i <= r; i++) {
            if (isp(i)) {
                if (lst) {
                    if (!l0 || r0 - l0 > i - lst) {
                        r0 = i, l0 = lst;
                    }
                    if (!l1 || r1 - l1 < i - lst) {
                        r1 = i, l1 = lst;
                    }
                }
                lst = i;
            }
        }
        if (l0) {
            printf("%u,%u are closest, %u,%u are most distant.\n", l0, r0, l1, r1);
        } else {
            puts("There are no adjacent primes.");
        }
    }
    return 0;
    // sample
    // 2146483647 2147483647
}

猜你喜欢

转载自blog.csdn.net/weixin_42068627/article/details/80845159
今日推荐