做了这道题就可以get一个新技能咯,就是传说中都没听过的bitset
1. 素数
【问题描述】
找出在[l,r]中的素数t,满足t=a^2+b^2(a,b为任意正整数),输出这种素数的数量。
【输入】
2个整数L,R
【输出】
答案
【输入样例】
6 66
【输出样例】
7
【样例解释】
对于30%的数据,L,R≤200。
对于70%的数据,L,R≤100000。
对于100%的数据,1<=L<R≤3*10^8。
这个题一看就觉得很水啊,但是看看数据范围,我方了。。。。随便怎么搞都不可能开到3*10^8啊!就算用线性筛,也没法保存,god!
那么这时候就有个神奇的东东叫做bitset滚了出来
详情请见下一篇博客(我堆了多少篇下一篇来着。。。不管了),也可以自己百度
反正bitset里一个元素只占1bit(二进制位),而8bit=1byte,所以可以开到3*1e8咯
然后我们根据题目可以推出,如果一个质数是两个数的平方和,那么它一定可以写成4k+1的形式
(感谢zxy大佬的讲解)
证明如下:a^2+b^2=素数,素数除2以外全是奇数,所以a^2+b^2答案是个奇数,
又已知奇数^2=奇数,偶数^2=偶数,奇数+偶数=奇数
所以最后答案一定是:(某一个奇数)^2+(某一个偶数)^2
然后用2n+1表示奇数,2n 表示偶数,然后打开括号就可以发现必然是4k+1
那么题目就转化为求l~r之间有多少个4k+1是质数
这就好搞啦,上代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bitset>
using namespace std;
bitset<300000000> f;
int l,r;
int main(){
scanf("%d%d",&l,&r);
int i,j,k,ans=0;
if(l<=2&&r>=2) ans=1;
for(i=3;i*i<=r;i+=2){//i+=2是为了直接忽略偶数,优化一下
if(!f[i])
for(j=i*i;j<=r;j+=2*i)
f[j]=1;
}
for(i=5;i<=r;i+=4)
if(l<=i&&!f[i]) ans++;
printf("%d",ans);
return 0;
}