【JZOJ 2298】 异或

题目大意:

\(\sum_{i=1}^{n}\sum_{j=i}^{n}[\gcd(i,j)==i\oplus j]\)

正文:

如果你实在想不出正解,你可能会用暴力把一段大范围以内的所有数对以及它们最大公约数(异或值),你会发现 \(i-j=k\)\(i,j\) 表示数对里的两个数,\(k\) 表示其最大公约数)。这是因为两个数 \(a,b\),和它们的最大公约数 \(c\) 的关系一定是 \(i-j\leq c\),而和它们的异或值 \(d\) 则是 \(i-j\geq d\),如果要最大公因数和异或值相等那么 \(i-j=k\)

通过这个式子,我们可以枚举 \(k\)\(i\) 得到 \(j\) 及答案。

代码:

int main()
{
	scanf("%d", &n);
	for (register int i = 1; i <= n / 2; i++)
		for (register int j = 2; i * j <= n; j++)
		{
			if(i * (j - 1) == ((i * j) ^ i)) 
			{
				ans += 1ll;
			}
		}	
	printf("%lld", ans);
	return 0;
}
posted @ 2020-08-11 19:50  Jayun  阅读(123)  评论(0编辑  收藏  举报