标签:
题意:给你一个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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u014664226/article/details/47742161