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

博客围绕哥德巴赫矩阵问题展开,根据哥德巴赫猜想定义矩阵,有若干询问需计算对应式子的值。分析指出这是线性筛素数模板题,用 num1 表示 x1 - x2 间奇素数,num2 表示 y1 - y2 间奇素数,答案为 num1 * num2,通过前缀和实现区间奇素数个数查询。

【题目】

题目描述:

根据哥德巴赫猜想(每个不小于 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

备注:

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值