【2018/08/29测试T1】【SDOJ 3727】哥德巴赫矩阵

【题目】

题目描述:

根据哥德巴赫猜想(每个不小于 6 的偶数都可以表示为两个奇素数之和),定义哥德巴赫矩阵 A 如下:对于正整数对(i,j),若 i+j 为偶数且 i , j 均为奇素数,则 A(i,j) = 1, 否则 A(i,j) = 0。现在有若干询问(x1,y1,x2,y2),你需要回答下列式子的值

\sum_{i=x1}^{x2}\sum_{j=y1}^{y2}A_{i,j}

输入格式:

第一行一个整数 m
接下来 m 行,每行四个整数 x1 y1 x2 y2,表示一个询问

输出格式:

m 行,每行一个整数,表示对应询问的答案

样例数据:

输入

1
1 1 3 5

输出

2

备注:

扫描二维码关注公众号,回复: 3092886 查看本文章

30% 的数据保证 x2 , y2 , m ≤ 100
100% 的数据保证 1 ≤ x1 ≤ x2 ≤ 10^{6};1 ≤ y1 ≤ y2 ≤ 10^{6};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;
}

猜你喜欢

转载自blog.csdn.net/forever_dreams/article/details/82181637