Description
质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。
根据算术基本定理,每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积;而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的。最小的质数是2。
目前为止,人们未找到一个公式可求出所有质数。
这道题想要你找出从L到R的区间内的所有质数。为了简化输出,你只需输出给定区间内的所有质数的和。
Input
t测试的数据个数。t<=500
接下来每组测试数据,有两个自然数,L和R。2 <= L <= R <= 10^12-1, R-L <= 106
Output
对每组自然数的区间L,R。输出从L到R中所有质數的和。
Sample Input
3
2 10
3 7
1000000 2000000
Sample Output
17
15
105363426899
这题咋一眼看好像有点难的样子
虽然范围是10^12,但是R-L是10^6。我们用a【i】来表示i+L是否为素数。
首先查找出 1-10^6的所以素数。用这个素数来做标记。素数的倍数(大于1倍)都是合数。最后求和。
AC代码:
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<vector>
#include<algorithm>
using
namespace
std;
typedef
long
long
ll;
const
int
size=1000010;
ll a[size],b[size],c[size],num;
void
init()
{
int
i,j;
num=0;
for
(i=2;i<1000010;i++)
{
if
(a[i]==0) b[num++]=i;
for
(j=0;j<num&&i*b[j]<1000010;j++)
{
a[i*b[j]]=1;
if
(i%b[j]==0)
break
;
}
}
}
int
main(){
init();
int
t;
ll l,r,e,bb,j,i;
scanf
(
"%d"
,&t);
while
(t--)
{
scanf
(
"%lld%lld"
,&l,&r);
memset
(c,0,
sizeof
(c));
for
(i=0;i<num;i++)
{
if
(l%b[i]==0) bb=l/b[i];
else
bb=l/b[i]+1;
e=r/b[i];
if
( bb<2 ) bb=2;
for
(j=bb;j<=e;j++) c[b[i]*j-l]=1;
}
ll ans=0;
for
(i=0;i<=r-l;i++)
if
(!c[i]) ans+=i+l;
cout<<ans<<endl;
}
return
0;
}