问题
分析
这道题是我自己做不出来的
记录下思路
这道题肯定不能同时枚举a,b,否则肯定TLE,所以只枚举a,然后计算b。
思路:这涉及到gcd和xor之间的关系,设
,那么由异或的性质,可以得到
。所以可以枚举a和它的因数c作为gcd,然后计算出b,最后验证是否有
.这种做法的时间复杂度:枚举a和它的因数c是O(nlgn),然后gcd是O(lgn),所以总的是
继续优化,发现满足
的元素都满足a-b=c
证明:a-b<=a xor b且a-b>=c,c=gcd(a,b)=a xor b,所以a-b=c
所以,可以枚举a,c,计算b=a-c,验证b=a^c是否成立,时间时O(lgn)
#include <cstring>
#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=30000000+1;
int cnt[maxn],s[maxn]; //cnt:前缀,cnt[i],a=i时的情况数
int main(void){
//类似埃氏筛的枚举方式
for(int c=1;c<maxn;++c){ //枚举c
for(int a=c*2;a<maxn;a+=c){ //枚举a
if(a-c==(a^c)){
cnt[a]++;
}
}
}
for(int i=1;i<maxn;++i) s[i]=s[i-1]+cnt[i];
int T=0,kase=0,n=0;
scanf("%d",&T);
while(kase<T){
scanf("%d",&n);
printf("Case %d: %d\n",++kase,s[n]);
}
return 0;
}