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