问题:
∀a<b≤N ∀ a < b ≤ N , 求有多少对 (a,b) ( a , b ) 使得 axorb=gcd(a,b) a x o r b = g c d ( a , b ) 。
推导:
满足条件的 (a,b) ( a , b ) 一定有 axorb=gcd(a,b)=b−a a x o r b = g c d ( a , b ) = b − a 。
证明:
-
gcd(a,b)≤b−a
g
c
d
(
a
,
b
)
≤
b
−
a
:
a,b a , b 均为 gcd(a,b) g c d ( a , b ) d的倍数,则 b−a b − a 也为其倍数,所以 gcd(a,b)≤b−a g c d ( a , b ) ≤ b − a 。
-
axorb≥b−a
a
x
o
r
b
≥
b
−
a
:
二进制下一共有4种减法情况:
b | a | c |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1(带借位) |
1 | 0 | 1 |
1 | 1 | 0 |
可以看出结果总是 a, b 的异或,并且可能带有借位,减小了实际值,所以有 axorb≥b−a a x o r b ≥ b − a
- 设 g=axorb=gcd(a,b) g = a x o r b = g c d ( a , b ) , 则有 g=b−a g = b − a
算法:
枚举 ĝ g ^ ,对其倍数 b̂ b ^ ,得到唯一的 â =ĝ xorb̂ a ^ = g ^ x o r b ^ ,检验是否有 ĝ =b̂ −â g ^ = b ^ − a ^ 。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N_MAX = 3e7 + 10;
int N;
int ans[N_MAX];
inline int est() {
int cnt = 0;
for (int c = 1; c <= N; c++) {
for (int a = c + c; a <= N; a += c) {
// divisor of a is c
if ((a - c) == (a ^ c)) {
cnt++;
ans[a]++;
}
}
}
return cnt;
}
int main() {
N = N_MAX - 1;
est();
for (int i = 1; i < N_MAX; i++) ans[i] += ans[i-1];
int T;
scanf("%d", &T);
int ks = 0;
while (T--) {
int x; scanf("%d", &x);
printf("Case %d: %d\n", ++ks, ans[x]);
}
}