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 xor operation on the binary representation of A and B.

Input

The first line of the input contains an integer T (T ≤ 10000) denoting the number of test cases. The
following T lines contain an integer N (1 ≤ N ≤ 30000000).

Output

For each test case, print the case number first in the format, ‘Case X:’ (here, X is the serial of the input) followed by a space and then the answer for that case. There is no new-line between cases.
Explanation
Sample 1: For N = 7, there are four valid pairs: (3, 2), (5, 4), (6, 4) and (7, 6).

Sample Input

2
7
20000000

Sample Output

Case 1: 4
Case 2: 34866117

题解

题意

输入整数n(1<=n<=3千万),有多少对整数(a,b)满足:1<=b<=a<=n,且gcd(a,b)=a XOR b。例如:n=7时,有4对:(3,2),(5,4),(6,4),(7,6)。

思路

有几个结论:

(1)若 a xor b = c,则 a xor c = b。

(2)a - b <= a xor b,(a >= b)

(3)若 gcd(a,b)= a xor b = c ,(a >= b),由(2)得:a - b <= c。

再令 a = k1×c,b = k2 × c,(k1 >= k2),所以 a - b = (k1 - k2)× c,所以 a - b >= c。总:a - b = c(这里若k1 = k2,那么 a = b,那么 a xor b = 0)

  然后就是怎么枚举的问题了,要保证计算量尽量小,如果枚举a,就要枚举a的所有因数,有些数因为可能是多个数的因数,会被重复考虑很多次。所以这里要枚举因数 c ,a = k × c(k >= 2) 这样每个因数只枚举一遍,再检验b。

代码

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;

#define REP(i,n) for(int i=0;i<(n);i++)

const int MAXN = 3e7+10;
int ans[MAXN];

void pre(){
    memset(ans,0,sizeof(ans));
    int top = MAXN >> 1,b;
    for(int c =1;c<=top;++c){
        for(int a=c+c;a<=MAXN;a+=c){
            b = a - c;
            if((a^b)==c) ++ans[a];
        }
    }
    for(int i =2;i<=MAXN;++i) ans[i]+=ans[i - 1];
}

int main(){
    pre();
    int T;
    scanf("%d",&T);
    int N;
    int kase = 0;
    while(T--){
        kase++;
        scanf("%d",&N);
        printf("Case %d: %d\n",kase,ans[N]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/caomingpei/p/9588259.html

时间: 2024-10-13 05:07:16

UVA12716 GCD XOR(枚举)的相关文章

UVA-12716 - GCD XOR

[思路]a^b = c等价于a^c = b  所以枚举a和c,而a和c全部枚举肯定TLE,所以高效算法:通过c是a的约数这个关系来枚举会减小循环,必须要将c放在循环外面,因为c的情况比较少.其实本题就是要求:c=a-b(规律),c=a^b 以下是高神的AC代码,很好很强大: #include <cstdio> #include <iostream> #include <cmath> #include <string> using namespace std;

UVA12716 GCD XOR 数论数学构造

题目给你一个N,让你求 两个数字 A,B,且   A>=B<=N,是的 gcd(A,B) == A^B N的范围是 3*10^7大的吓人一开始没敢想构造,因为就算构造开的数组也太大了,已经10^7了,后来想了半天在^运算这里也没有想出来什么,所以没办法还是大胆构造吧,构造就去按照他题目的意思来了,构造两个数字 i,j其中j是i的倍数,那么j + i与i的最大公约数肯定是i了,那么(j+i)^i == i这样构造出来的就算满足了,然后再模仿gcd辗转相除的愿意  把它们放在一个数组里计数,这样预

[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

UVa12716 - GCD XOR

题意 给一个数n,找出gcd(a,b) = a^b的个数   (1<=b<=a<=n). n的数据范围:1到30000000 思路 c满足gcd(a,b) = a^b,打表观察数据得出c = a - b:又因为c是a的约数,用类似素数筛选的方法降低时间复杂度. 总结 敲代码的时候忘记打表这个东西的存在,只要一次性将所有的结果算出存在数组里,每次提取就可以,不用每次都算一遍. 智障啊_(:з」∠)_为什么想不到,不然又可以A一道题 #include <iostream> #in

uva12716 GCD XOR(打表找规律+筛法)

题意:输入整数(1=<n<=30000000),有多少对整数(a,b)满足:1=<b=<a=<n,且gcd(a,b)=a^b.例如n=7时,有4对:(3,2),(5,4),(6,4),(7,6) 解题思路: 看到题目之后一直在找最大公约数和异或之间的关系,但找了半天没有发现.于是果断打表发现如下规律 满足gcd(a,b)=a^b的数有如下规律,要么就是a=b-1,要么就是有前面已求得的满足条件的乘上一定的倍数得到如下: 根据上述规律,我们便可以求的所有的可能性,上面只打印了一

【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;

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 (异或)

题意:求出[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

uva12716 gcd

题意:给出N,1<=b<=a<=N,求满足gcd(a,b)=a xor b的pair (a,b)的个数 有个重要的结论:若gcd(a,b)=a xor b=c,那么b=a-c 如果一个个求gcd肯定不行. 令f[i]表示满足条件的pair (a,b)中,a=i的个数 枚举c,令a是c的所有倍数,求出b=a-c.若b=a xor c那么f[a]++ 最后求f[]的前缀和S[],那么答案就是S[N](要求a<=N啦~) 1 #include <stdio.h> 2 #inc