输入一个整数,有多少对(a,b)满足1<=b<=a<=n,且
gcd(a,b) = a xor b
gcd是最大公约数
xor 是 异或运算,2进制 1001^1011=0010 相同为0,不同为1
设gcd(a,b) = a xor b = c
打印一些满足条件的a,b,c,然后发现c = a - b
有了这个规律就大大节约了时间,遍历a和c,用a-c表示b
在遍历的时候,因为c是a的最大公约数,所以a = c + c,然后a += c,这样就避免了gcd的耗时
#include<iostream>
using namespace std;
const int MAXN = 30000010;
int vis[MAXN];
void init() {
for(int c = 1; c < MAXN; c++) {//优先循环c
for(int a = c + c; a < MAXN; a += c) {//a是c的倍数
if((a ^ (a - c) )== c) {//现在gcd(a,b)==c了,只需异或判断
vis[a]++; //这里是每个a对应的个数
}
}
vis[c] += vis[c - 1];//因为需要统计所有个数,需要把前面的加到后面
}
}
int main() {
int t, kase = 0;
cin >> t;
init();
while(t--) {
int n;
cin >> n;
printf("Case %d: ", ++kase);
cout << vis[n] << endl;
}
return 0;
}