题意:输入整数n(1<=n<=30000000),有多少对整数(a,b)满足1<=b<=a<=n,且gcd(a,b)=a xor b。
题解:设c=gcd(a,b),因为a-b<=a xor b,且a-b>=c,假设存在c是的a-b>c,则c<a-b<=a xor b,与c= a xor b矛盾。所以c =a-b。所以枚举a和c,计算b=a-c,则gcd(a,b)=gcd(a,a-c)=c,因此只需要验证是否有c= a xor b即可。
a-b<=a xor b ,因为异或运算是不同的话为一。所以除非a=b否则a xor b必定大于a-b(a>=b),因为在二进制位中,对于每一位,a-b只要是不同,那么必定是正或负,而对于啊xorb来说,只要是不同就是正,由于相同的在2种运算中都是0,因而无影响。由上述推理可得a xor b必定大于或者等于a-b(a>=b)。(xor 表示异或)。
#include<cstdio> #include<cstring> using namespace std; const int M = 30000000; int cnt[M+1], sum[M+1]; void init() { memset(cnt, 0, sizeof(cnt)); for(int c = 1; c <= M; c++) for(int a = c*2; a <= M; a += c) {///因为a>=b,所以需要从2*c开始枚举 int b = a - c; if(c == (a ^ b)) cnt[a]++;///统计每个a对应的b的数量 } sum[0] = 0; for(int i = 1; i <= M; i++) sum[i] = sum[i-1] + cnt[i]; } int main(){ init(); int T, n, kase = 0; scanf("%d", &T); while(T--) { scanf("%d", &n); printf("Case %d: %d\n", ++kase, sum[n]); } return 0; }
浙公网安备 33010602011771号