uva10200——前缀和+质数判定
发布日期:2021-05-18 06:05:29 浏览次数:20 分类:精选文章

本文共 1732 字,大约阅读时间需要 5 分钟。

为了解决这个问题,我们需要计算Euler公式 ( n^2 + n + 41 ) 在给定区间 ([a, b]) 内生成的质数的百分比。为了高效处理这个问题,我们可以预先计算每个数 ( n ) 是否生成质数,然后在查询时快速统计结果。

方法思路

  • 预处理阶段:我们预先计算每个 ( n ) 从 0 到 10000 时,( n^2 + n + 41 ) 是否为质数,并记录下来。使用前缀和数组 sum,其中 sum[i] 表示从 0 到 i 的数中生成质数的个数。
  • 判断质数:使用试除法来判断一个数是否为质数。通过预先计算,我们可以在常数时间内得到结果。
  • 查询处理:对于每个查询,使用预处理好的前缀和数组快速计算区间内的质数个数和总数,进而计算百分比。
  • 解决代码

    #include 
    #include
    #include
    using namespace std;const int maxn = 10000 + 5;int sum[maxn + 1];void init_sum() { sum[0] = 1; for (int i = 1; i <= maxn; ++i) { int x = i * i + i + 41; if (x <= 1) { sum[i] = sum[i - 1]; continue; } bool is_prime = true; if (x % 2 == 0 || x % 3 == 0) { is_prime = false; } else { for (int j = 5; j * j <= x; j += 6) { if (x % j == 0 || x % (j + 2) == 0) { is_prime = false; break; } } } sum[i] = is_prime ? sum[i - 1] + 1 : sum[i - 1]; }}int main() { init_sum(); while (true) { long long a, b; if (scanf("%lld%lld", &a, &b) != 2) { break; } if (a > b) { a = b; } long long count = sum[b]; if (a > 0) { count -= sum[a - 1]; } long long total = b - a + 1; double percent = (count * 100.0) / total; percent = round(percent * 100.0) / 100.0; printf("%.2f\n", percent); } return 0;}

    代码解释

  • 预处理阶段:函数 init_sum 计算每个 ( n )(从 0 到 10000)时,( n^2 + n + 41 ) 是否为质数,并记录在数组 sum 中。
  • 质数判断:使用试除法判断一个数是否为质数,优化了判断过程,特别是通过跳过偶数和3的倍数来减少计算量。
  • 查询处理:对于每个输入的区间 ([a, b]),使用预处理好的前缀和数组快速计算质数个数和总数,计算出质数的百分比,并输出结果。
  • 这种方法通过预处理阶段将时间复杂度降低到常数时间,确保了在处理大量查询时的高效性。

    上一篇:uva11827——最大公约数+输入处理(stringstream)
    下一篇:poj2116——模拟

    发表评论

    最新留言

    能坚持,总会有不一样的收获!
    [***.219.124.196]2025年05月09日 10时03分53秒