您的位置:首页 > 移动开发

Codeforces Beta Round #86 (Div. 2 Only) E Double Happiness 素数筛法,费马平方和定理

2017-10-08 19:40 447 查看
题目链接

E. 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] (l ≤ r)
are suitable for pair programming. They decided that the day i(l ≤ i ≤ r)
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


题目大意:求一个区间内满足,a^2+b^2=prime的(a,b)的数对。

题目思路:费马平方和定理,一个奇素数可以分解为两个数的平方和,那么这个奇素素一定是 4k+1 型的。(注意特判下2)

所以我们筛素数的同时对每个数判断一下。

然后我们要剪枝和优化,大概如下几点:

1:偶数全部都不满足,直接算而不用放进筛法里。

2:只用用奇素数进行素数筛,而且只晒出没有偶数因子的数。

3:筛法和判定一个数是否满足题目的条件同时进行。

4:bool[3e8]的内存是不够的,我们需要用bitset优化,bitset的空间,关于这个,我请教了一下q巨。



所以我们一般在windows64 下可以节省8倍空间

然后记得处理一下细节,即2这个素数不满足4k+1 型,但是它也是满足a^2+b^2的。

代码如下

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e8+10;
bitset<maxn>prime;
int Getprime(int l,int r)
{
int cnt=0;
if(l<=2&&2<=r) cnt++;
l=max(l,3);
if(l>r) return cnt;
if(l%2==0&&r%2==0) cnt-=(r-l+2)>>1;//减去偶数不满足的情况
else if(l%2&&r%2) cnt-=(r-l)>>1;
else if(l%2||r%2) cnt-=(r-l+1)>>1;
cnt+=r-l+1;
prime.reset();
prime[0]=true;
prime[1]=true;
int i;
for(i=3;i*i<=r;i+=2)
{
if(prime[i])
{
if(i>=l) cnt--;
continue;
}
if(i>=l&&(i-1)%4) cnt--;
for(int j=i*i;j<=r;j+=i<<1) prime[j]=true;
}
if(l%2==0) l++;
i=max(l,i);
for(;i<=r;i+=2)
{
if(prime[i]||(i-1)%4) cnt--;
}
return cnt;
}
int main()
{
int l,r;
while(~scanf("%d%d",&l,&r))
{
cout<<Getprime(l,r)<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: