题目大意
输入数据组数t,接下来t行每行给定一个数字n,设1<=b<=a<=n,求gcd(a,b)==a xor b的(a,b)二元组个数。
解析
关于xor几条性质
1.若a xor b=c,则b xor c=a;
2.a-b<=a xor b (a>=b).
设gcd(a,b)=c,则可设a=x*c,b=y*c;a-b = (x-y)*c, 则a-b>=c,得a-b<=c;因此可知a-b=c;
此时可先枚举a,c,得到b,再对其进行gcd(a,b)是否为c进行验证,若行则进行累加。时间大约是1060ms。
#include<bits/stdc++.h> using namespace std; int al[30000001]; void cl(){ for(int i=1;i<=15000000;i++) for(int j=2*i;j<=30000000;j+=i){ int l=j-i; if(i==(j^l)) al[j]++; } for(int i=2;i<=30000000;i++) al[i]+=al[i-1]; } int main(){ int t=0,T,n; cl(); scanf("%d",&T); while(T--){ scanf("%d",&n); t++; cout<<"Case "<<t<<": "<<al[n]<<endl;; } return 0; }