【题目】
题目描述:
根据哥德巴赫猜想(每个不小于 6 的偶数都可以表示为两个奇素数之和),定义哥德巴赫矩阵 A 如下:对于正整数对(i,j),若 i+j 为偶数且 i , j 均为奇素数,则 A(i,j) = 1, 否则 A(i,j) = 0。现在有若干询问(x1,y1,x2,y2),你需要回答下列式子的值
输入格式:
第一行一个整数 m
接下来 m 行,每行四个整数 x1 y1 x2 y2,表示一个询问
输出格式:
m 行,每行一个整数,表示对应询问的答案
样例数据:
输入
1 1 1 3 5
输出
2
备注:
扫描二维码关注公众号,回复:
3092886 查看本文章
30% 的数据保证 x2 , y2 , m ≤ 100
100% 的数据保证 1 ≤ x1 ≤ x2 ≤ ;1 ≤ y1 ≤ y2 ≤ ;m ≤ 1000
【分析】
其实这就是一道线性筛素数模板题
我们用 num1 表示 x1~x2 间的奇素数,num2 表示 y1~y2 间的奇素数,最后的答案就是 num1 * num2
查询区间奇素数的个数的话我们用前缀和来实现
很简单是不是~~~
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Max 1000005
using namespace std;
int num[Max],prime[Max];
bool mark[Max];
void init()
{
int i,j,sum=0;
memset(mark,true,sizeof(mark));
mark[0]=mark[1]=false;
for(i=2;i<=Max;++i)
{
num[i]=num[i-1];
if(mark[i]) prime[++sum]=i,num[i]++;
for(j=1;j<=sum&&i*prime[j]<=Max;++j)
{
mark[i*prime[j]]=false;
if(i%prime[j]==0) break;
}
}
for(i=2;i<=Max;++i)
num[i]--;
}
int main()
{
// freopen("pmatrix.in","r",stdin);
// freopen("pmatrix.out","w",stdout);
int n,i;
int x1,y1,x2,y2;
long long ans;
scanf("%d",&n);
init();
for(i=1;i<=n;++i)
{
scanf("%d%d",&x1,&y1);
scanf("%d%d",&x2,&y2);
ans=1ll*(num[x2]-num[x1-1])*(num[y2]-num[y1-1]);
printf("%lld\n",ans);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}