题目:UVA 12716
约定a >= b, (a, b) = c. 那么 c <= (a, b). 应该知道(a, b)意为最大公约数gcd
a ^ b = c === c <= a ^ b,
a 不能等于 b, 反正法:若a= b, a ^ b = 0. 而 (a, b) = a != 0。不会满足题意的。得知 c <= a - b <= a ^ b = c,所以 c = a - b
就下来就是暴力枚举因数c, 和 a.时间复杂度O(nlogn)。一次离线处理即可。
\
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;
const int maxn = 3e7;
long long f[maxn + 1];
void init() { //离线预处理
memset(f, 0, sizeof f);
int maxC = maxn / 2; //gcd最大为最大数值的一般对吧
for(int c = 1; c <= maxC; ++c) { //枚举最大公约数
for(int i = 2; i * c <= maxn; ++i) { //枚举因子
int a = i * c;
int b = a ^ c;
if(a - b == c) {
f[a]++;
}
}
}
for(int i = 2; i <= maxn; ++i)
f[i] += f[i - 1];
}
int main()
{
init();//预处理
int T, kase = 0;
cin >> T;
while(T--) {
int n;
cin >> n;
cout << "Case " << ++kase << ": " << f[n] << endl;
}
return 0;
}
\