题意:给你一个N,让你求有多少组A,B, 满足1<= B <= A <= N, 且 gcd(A,B) = A XOR B。
思路:首先我们能够得出两个结论:
A-B >= A%B >= gcd(A, B)
A xor B >= A-B
所以说A xor B >= A-B >= gcd(A, B),然后就能够推出
A xor B = A - B = gcd(A, B) => A xor B = A - B && A - B = gcd(A, B)
设 C = gcd(A, B),那么我们能够枚举C和A。通过A-C求出B,再验证A xor B 是否等于C就可以
这里的枚举是仿照筛素数的方法,对于每个A。我们求出一共同拥有多少C满足条件,记为ans[A],那么最后仅仅须要累加一下就能够。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define LL long long
#define pii (pair<int, int>)
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;const int maxn = 30000000 + 10000;
//const int INF = 0x3f3f3f3f;
int n;
int ans[maxn];void init() {for(int c = 1; c <= 30000000; c++) {for(int a = c<<1; a <= 30000000; a += c) {int b = a - c;if((a^b) == a-b) ans[a]++;}}for(int i = 1; i <= 30000000; i++) ans[i] += ans[i-1];
}int main() {//freopen("input.txt", "r", stdin);int T; cin >> T;int kase = 0;init();while(T--) {scanf("%d", &n);printf("Case %d: %d\n", ++kase, ans[n]);}return 0;
}