【问题标题】:Segmented sieve of eratosthenes spoj Prime1 C++Eratosthenes spoj Prime1 C++ 的分段筛
【发布时间】:2016-04-06 10:57:22
【问题描述】:

我一直在努力解决这个问题http://www.spoj.com/problems/PRIME1/,如果有人可以帮助我在我的代码中找到错误。我使用了 Eratosthenes 的分段筛,我还查看了很多在线资源,但不知何故我在 spoj 上遇到了运行时错误。 谢谢

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <string>
    #include <cmath>
    #include <map>
    #include <cstdlib>
    #include <cassert>
    #define fora(i,a,b) for(i = a; i < b; i++)
    #define fin(f) freopen(f, "r", stdin)
    #define fout(f) freopen(f, "w", stdout)
    using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;
typedef vector<bool> vb;

const ll LIMIT = 1000000000;

void segmentedSieve(ll n, ll m, int segment_size) {
    int i, j, s, p, range;
    vb is_prime(range+1, true);
    vb seg_primes(segment_size+1, true);
    vi prime;

    range = floor(sqrt((double)n));

    fora (i, 2, range+1)
        if (is_prime[i]) {
            for (j = i*2; j <= range; j+=i)
                is_prime[j] = false;
        }

    fora (i, 2, range+1)
        if (is_prime[i] == 1)
            prime.push_back(i);

    fora (i, 0, prime.size()) {
        p = prime[i];
        s = m/p;
        s *= p;

        for (j = s; j <= n; j+=p) {
            if (j < m) continue;
            seg_primes[j-m] = false;
        }
    }

    fora (i, 0, prime.size())
        if (prime[i] >= m && prime[i] <= n) {
            cout << prime[i] << endl;
        }

    fora (i, 0, n-m+1)
        if (seg_primes[i] && (i+m) != 1) {
            cout << i+m << endl;
        }
}

int main()
{
    int segment_size = 100000;
    // fin("input.in");
    int t;
    cin >> t;
    while (t--) {
        ll a, b;
        cin >> a >> b;
        if (a > b)
            segmentedSieve(a, b, segment_size);
        else
            segmentedSieve(b, a, segment_size);
        if (t != 0)
            cout << endl;
    }
}

【问题讨论】:

  • 现在是学习使用调试器的时候了。 (帮自己一个忙,删除那些宏,它们太可怕了。)
  • 那些宏除了混淆代码之外什么都没有。不需要用宏定义for 循环——我们都知道for 循环是什么样子的。我们都知道long long 是什么,等等。我同意马特的观点,他们太可怕了。至于long long,几天前我看到另一个使用相同可怕宏的 SPOJ 帖子。 SPOJ 教你使用这个吗?
  • 哈哈哈...只是有助于更快地编写代码:P

标签: c++ runtime primes sieve-of-eratosthenes


【解决方案1】:

range 似乎在这里未初始化:

void segmentedSieve(ll n, ll m, int segment_size) {
    int i, j, s, p, range;
    vb is_prime(range+1, true);   // uninitialized range... !!

也许你想要

void segmentedSieve(ll n, ll m, int segment_size) {
    int i, j, s, p, range;

    range = floor(sqrt((double)n));  // This first...

    vb is_prime(range+1, true);      // then this

如果可能,您应该在定义变量时对其进行初始化。

void segmentedSieve(ll n, ll m, int segment_size) {
    int i, j, s, p; // no range here

    int range = floor(sqrt((double)n));  // This first...

    vb is_prime(range+1, true);      // then this

一般来说,您应该将变量的定义推迟到您需要它们之前,即不要在开始时定义所有变量,而是根据需要进行定义。

附言正如其他人已经评论的那样 - 摆脱所有宏的东西......

【讨论】:

  • 非常感谢...是的,我们也将摆脱这些宏
猜你喜欢
  • 1970-01-01
  • 2014-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多