poj3511

如果一个质数可以表示成4x+1的形式,那么它一定可以表示成两个数字的平方和。(2是特殊情况)

用素数筛打素数,并用以上定理判断是否能表示成平方和,预处理好后,对于每个询问用O(1)时间输出。

注意边界值可能为负数,负数中没有质数。

View Code
#include <iostream>

#include <cstdlib>

#include <cstdio>

#include <cstring>

#include <cmath>

using namespace std;



#define maxn 1000005



bool is[maxn];

int prm[maxn];

int x[maxn];

int y[maxn];



int getprm(int n)

{

    int i, j, k = 0;

    int s, e = (int) (sqrt(0.0 + n) + 1);



    memset(is, 1, sizeof(is));

    prm[k++] = 2;

    is[0] = is[1] = 0;

    for (i = 4; i < n; i += 2)

        is[i] = 0;

    for (i = 3; i < e; i += 2)

        if (is[i])

        {

            prm[k++] = i;

            for (s = i * 2, j = i * i; j < n; j += s)

                is[j] = 0;

        }

    for (; i < n; i += 2)

        if (is[i])

            prm[k++] = i;

    return k;

}



int main()

{

    //freopen("t.txt", "r", stdin);

    getprm(1000000);

    x[0] = 0;

    for (int i = 1; i < 1000000; i++)

        if (is[i])

            x[i] = x[i - 1] + 1;

        else

            x[i] = x[i - 1];

    y[2] = 1;

    for (int i = 3; i < 1000000; i++)

        if (is[i] && i % 4 == 1)

            y[i] = y[i - 1] + 1;

        else

            y[i] = y[i - 1];

    int l, u;

    while (scanf("%d%d", &l, &u), ~l || ~u)

    {

        int ll = l - 1;

        ll = max(ll, 0);

        int uu = max(u, 0);

        printf("%d %d %d %d\n", l, u, x[uu] - x[ll], y[uu] - y[ll]);

    }

    return 0;

}

你可能感兴趣的:(poj)