[UVA-12716] GCD XOR 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接(vjudge):https://vjudge.net/problem/UVA-12716

题目大意:

输入一个数字t,表示数据组数。

接下来t行,每行给出一个整数n(1<=n<=30000000),问有多少对整数a,b(1<=b<=a<=n),满足gcd(a,b) = a^b。

对于每个n,输出Case x: y,表示当前是第x组数据,结果是y。

Sample Input

2

7

20000000

Sample Output

Case 1: 4

Case 2: 34866117

分析:

详见《算法竞赛入门经典》P318

最普遍的想法就是写一个暴力,二重循环a,b枚举出所有的可能解。

尝试输出a,b和gcd(a,b)(设为c)的值,会发现c = a-b.

于是就可以只枚举a和c,算出b,再判断a^b是否等于c.

注意要把c放在外重循环,a放在内重循环。

AC代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5
 6 const int MAXN = 30000005;
 7
 8 int gcd(int a,int b)
 9 {
10     if(b == 0) return a;
11     return gcd(b,a%b);
12 }
13
14 int cnt,tmp,mx,ans,t,n[MAXN],f[MAXN];
15
16 int main()
17 {
18 //    freopen("1.txt","r",stdin);
19     scanf("%d",&t);
20     for(int i = 1;i <= t;++ i){
21         scanf("%d",&n[i]);
22         if(n[i] > mx) mx = n[i];
23     }
24     for(int i = 1;i <= mx/2;++ i)
25         for(int j = i+i;j <= mx;j += i)
26             if((j^(j-i)) == i)
27                 f[j] ++;
28     for(int j = 2;j <= mx;++ j)
29         f[j] += f[j-1];
30     for(int i = 1;i <= t;++ i)
31         printf("Case %d: %d\n",i,f[n[i]]);
32     return 0;
33 }
时间: 2024-10-30 20:53:04

[UVA-12716] GCD XOR 题解的相关文章

UVA 12716 GCD XOR (异或)

题意:求出[1,n]中满足gcd(a,b)=a xor b,且1<=a<=b<=n的对数 题解:首先a xor b = c,则a xor c = b,而b是a的约数,则可以使用素数筛选法的方法使用O(nlogn)枚举a与c      接着gcd需要O(logn)的时间,时间为O(n(logn)^2) 但是我们还可以继续优化掉一个log,我们打表找规律可以看出c=a-b 证明:因为a - b(相同为0,不同为1或者-1) <=a xor b(相同为0,不同为1),又因为gcd(a,b

UVA 12716 GCD XOR(数论+枚举+打表)

 题意:给你一个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 -

UVa 12716 (GCD == XOR) GCD XOR

题意: 问整数n以内,有多少对整数a.b满足(1≤b≤a)且gcd(a, b) = xor(a, b) 分析: gcd和xor看起来风马牛不相及的运算,居然有一个比较"神奇"的结论: 设gcd(a, b) = xor(a, b) = c, 则 c = a - b 这里 有比较严格的证明. 有了这个结论后,我们可以枚举约数c,然后枚举c的倍数a,再根据c = a - b计算b,检验b是否满足gcd(a, b) = xor(a, b) 1 #include <cstdio> 2

UVA 12716 GCD XOR【异或】

参考:http://www.cnblogs.com/naturepengchen/articles/3952145.html #include<stdio.h> #include<string.h> #include<time.h> const int N=3e7+11; int ans[N]; int gcd(int a,int b){ if(!b) return a; return gcd(b,a%b); } void init(){ for(int c=1;c&l

UVa 12716 GCD XOR (简单证明)

题意: 问 gcd(i,j) = i ^ j  的对数(j <=i <= N ) N的范围为30000000,有10000组例子 思路:GCD(a,b) = a^b = c GCD(a/c,b/c) = 1 (1) (a-b) <= c (2) (a/c-b/c) <=1 (3) (1)(3) => a/c-b/c = 1=> a-b=c #include <iostream> #include <cstdio> #include <cst

uva 11388 GCD LCM题解

题意:输入两个数G,L,找出两个数a,b,使得gcd(a,b)=G,lcm(a,b)=L.有多解输出a最小的那个.无解输出-1. 嗯,这是一道值得思考5s的题目. L%G==0即有解,否则无解. 有解的话我们让a=G,b=L.这样a一定是最小,且合法. 1 #include<cstdio> 2 int T,G,L; 3 int main() 4 { 5 scanf("%d",&T); 6 while(T--) 7 { 8 scanf("%d%d"

【UVA】12716-GCD XOR

做出做道题需要注意2个地方: 首先可以打表找规律,找到规律我们可以发现: 1.如果gcd(a,b) = a ^ b = c,那么 b = a - c; 既然这样我们可以枚举a,c,求出b之后判断 c 是否等于 a ^ b,那么如何枚举c呢? 2.利用类似筛选素数的方法去枚举a,c 首先c是a的约数,所以这道题我们需要枚举的其实是a的约数,但是约数也不好枚举,我们可以通过c去枚举a,我们通过枚举c,找到约数是c的所有a. 这题由于数据过大,需要打表,否则超时. 14024658 12716 GCD

UVA12716 GCD XOR(枚举)

UVA12716 GCD XOR Description 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

【Math】GCD XOR 证明

题目:Given an integer N, and how many pairs (A;B) are there such that: gcd(A;B) = A xor B where 1<=B<=A<=N. 首先先爆一发,妥妥超时.其实真相是我想打表找规律.结果没什么规律可循. 后来分析:要想让GCD(A,B)==(A^B),A和B一定是同样的位数(二进制).因此打表方法可变为:(亦超时) void init() { int K=0; int last=0; for(int i=1;