UVA12716 GCD XOR

Given an integer N, find how many pairs (A, B) are there such that: gcd(A, B) = A xor B where 1 ≤ B ≤ A ≤ N. Here gcd(A, B) means the greatest common divisor of the numbers A and B. And A xor B is the value of the bitwise xor operation on the binary representation of A and B.

Input

The first line of the input contains an integer T (T ≤ 10000) denoting the number of test cases.The following T lines contain an integer N (1 ≤ N ≤ 30000000).

Output

For each test case, print the case number first in the format, ‘Case X:’ (here, X is the serial of the input) followed by a space and then the answer for that case. There is no new-line between cases.

Explanation Sample 1: For N = 7, there are four valid pairs: (3, 2), (5, 4), (6, 4) and (7, 6).

Sample Input

2

7

20000000

Sample Output

Case 1: 4

Case 2: 34866117

先要证明gcd( a , b ) == a xor b 时,gcd( a , b ) == a xor b == a - b

它是根据 gcd( a , b ) <= a - b <= a xor b 得来的。gcd( a , b ) <= a - b 很容易理解,但是a - b <= a xor b 需要画图。

第一个圆表示b转化为二进制后1的所有位置,第二个圆表示a转化为二进制后1的所有位置,两圆相交部分为a与b对应位置都为1的部分

设蓝色部分为x,黄色部分为y。a xor b 就是 x + y,a - b 就是 x - y。所以 a - b <= a xor b

然后根据这个结论去枚举 c(= a xor b = gcd( a , b ) = a - b)和 a (a 是 c 的倍数),判断 b(= a - c)是否满足 a xor b == c 即 a xor c == b

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=3e7+10;
int T,n;long long ans[maxn];

long long aa;char cc;
long long read() {
	aa=0;cc=getchar();
	while(cc<'0'||cc>'9') cc=getchar();
	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
	return aa;
}

int main() {
	T=read();int a,b,c;
	for(c=1;c<=maxn/2;++c)
		for(a=c+c;a<=maxn;a+=c) {
			b=a-c;
			if((a^b)==c) ans[a]++;
		}
	for(int i=2;i<=maxn;++i) ans[i]+=ans[i-1];
	
	for(int qaq=1;qaq<=T;++qaq) {
		n=read();
		printf("Case %d: %lld
",qaq,ans[n]);
	}
	return 0;
}

  

弱者就是会被欺负呀
原文地址:https://www.cnblogs.com/Serene-shixinyi/p/7511952.html