UVA 12716 GCD XOR (数论 gcd和异或不等式)

78 篇文章 0 订阅

GCD XOR


题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4454


题目大意:求gcd(a, b) = a ^ b且满足1 <= b <= a <= N的(a, b)对数,其中N小于等于3e7


样例:

SampleInput
2
7
20000000

SampleOutput
Case 1: 4
Case 2: 34866117


题目分析:首先若a == b则显然gcd(a, b) != a ^ b,在b < a时考虑两个不等式:

1. gcd(a, b) <= a - b,这个不用解释了

2. a ^ b >= a - b,设a >= b把a,b化成二进制,假设ai位为0,对应的bi位为1,则交换它们,异或值不会变化,但是a - b变大了,因此把所有对应位置中ai与bi不同的位置处令ai为1,bi为0,则得到a ^ b == a - b,其余的a ^ b显然都是大于a - b的,因此结论成立

又因为a ^ b = c => a ^ c = b,这个好证:a ^ b = c => a ^ a ^ b = a ^ c => b = a ^ c

由以上推论可得若gcd(a, b) = a ^ b则a ^ b = a - b 且 gcd(a, b) = a - b,因此a - b是a的约数,因此可以枚举a-b的值,用筛子得到a,再判断是否有a ^ b = a - b即可,预处理前n个数的(a, b)对数,O(1)查询

#include <cstdio>
int const MAX = 30000005;
int ans[MAX];

void pre()
{
	for(int i = 1; i < MAX; i++) // i 即 a - b
	{
		for(int j = i + i; j < MAX; j += i)  // j 即 a
			if((j ^ (j - i)) == i) // 判断是否有 a ^ b == a - b
				ans[j] ++;
		ans[i] += ans[i - 1];
	}
}

int main()
{
	pre();
	int T;
	scanf("%d", &T);
	for(int ca = 1; ca <= T; ca++)
	{
		int n;
		scanf("%d", &n);
		printf("Case %d: %d\n", ca, ans[n]);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值