1. 程式人生 > >cf Double Happiness(判斷是否為素數且為4k+1型)

cf Double Happiness(判斷是否為素數且為4k+1型)

2790. Double Happiness

 

 

time limit per test 3 seconds memory limit per test 128 megabytes input standard input output
standard output

On the math lesson a teacher asked each pupil to come up with his own lucky numbers. As a fan of number theory Peter chose prime numbers. Bob was more original. He said that number t is his lucky number, if it can be represented as:

t
=a2+b2,
where a,b are arbitrary positive integers.

Now, the boys decided to find out how many days of the interval [l,r] (lr) are suitable for pair programming. They decided that the day i(lir) is suitable for pair programming if and only if the number i

 is lucky for Peter and lucky for Bob at the same time. Help the boys to find the number of such days.

Input

The first line of the input contains integer numbers l,r (1≤l,r≤3·108).

Output

In the only line print the number of days on the segment [l,r], which are lucky for Peter and Bob at the same time.

Examples Input
3 5
Output
1
Input
6 66
Output
7

題目分析:
兩位同學的幸運數字一個是為素數,一個是可以表示為兩整數平方和的數字。
這裡只是想補充一個數論的知識:一個4k+1型的素數,一定可以分解為兩個整數的平方和。
知道了這個知識後,一定程度上簡化此題。最後一個要解決的問題就是,如何快速的判斷一個較大數字是否為素數。
這個地方需要,瞭解“埃拉託斯特尼篩法”,以下簡稱埃氏篩
所謂“埃氏篩”就是,要得到n以內的所有素數,必須把不大於n的所有素數的整數倍剔除,剩下的數字就是素數。
另外r,l的取值範圍最大取到3e8,如果建立一個容量是3e8的bool型陣列,必定要炸記憶體,所以要設法精簡下。
· 所有的素數都是奇數,所有可以找到一種對應關係,3/2=1,5/2=2,7/2=3,嗯,這樣就可以把陣列的長度折半。
#include <stdio.h>   
#include <iostream>  
#include <vector>
using namespace std;
const long maxn = 3e8 + 5;
vector<bool> b(maxn >> 1, 0);//集體賦為0
int main()
{
    long l;
    long r;
    long i;
    long j;
    for (i = 3; i*i <= maxn; i += 2)//埃氏篩
        if (!b[i >> 1])//0 is 素數
            for (j = i * i; j <= maxn; j += (i << 1)) {
                b[j >> 1] = 1;//1 is 非素數
            }

    while (cin >> l >> r) {
        long ans = 0;
        if (l <= 2 && r >= 2) ans++;
        while (l % 4 != 1)l++;
        while (r % 4 != 1)r--;
        for (i = l; i <= r; i += 4)
            if (i >= l && !b[i >> 1])
                ans++;
        cout << ans << endl;
    }
    return 0;
}