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 <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <cmath>
using namespace std;
const int maxn = 30000000+10;
typedef long long LL;
int N;
int ret[maxn];

void init() {
    for(int i = 3; i < maxn; i+=2) ret[i] = 1;
    for(int i = 2; i < maxn/2; i++) {
        for(int j = i+i; j < maxn; j += i) {
            int k = j-i;
            if( (k^j) == i){
                ret[j]++;
            }
        }
    }
    for(int i = 1; i < maxn; i++) ret[i] += ret[i-1];
}
int main(){
    int ncase,T=1;
    init();
    cin >> ncase;
    while(ncase--) {
        scanf("%d",&N);
        printf("Case %d: %d\n",T++,ret[N]);
    }
    return 0;
}
时间: 2024-10-20 15:22:26

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) 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(数论+枚举+打表)

 题意:给你一个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【异或】

参考: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

做出做道题需要注意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

【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 11388 GCD LCM ( 数论 )

Uva  11388 GCD LCM( 数论 ) 题意: 求是否存在a,b 使得lcm(a,b) = L, gcd(a,b) = G,不存在输出-1,存在输出a,b,且a尽可能小 分析: 强行暴力是不可能的数据很大,要用llu,这里有两种思路 思路一: 由题意可知 a*b = G*L 保证a = G的倍数的情况下,枚举a再判断G*L能否整除a,最后判断b是否为a的倍数.a从G开始扫到sqrt(G*L) //输入两个整数G,L //找出a,b 使得 gcd(a,b) = G lcm(a,b) =

uva 1521 - GCD Guessing Game(贪心)

题目链接:uva 1521 - GCD Guessing Game 题目大意:给定一个数N,现在又一个数x,在1~N之间,现在每次可以猜一个数a,返回gcd(x,a),问说最少猜几次可以确定x. 解题思路:其实就将1~N里面的素数都要考虑一遍,因为有一个N的限制,所以每次选出来的素数的积不大于N即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const

UVA - 11388 GCD LCM

II U C   ONLINE   C ON TEST   2 008 Problem D: GCD LCM Input: standard input Output: standard output The GCD of two positive integers is the largest integer that divides both the integers without any remainder. The LCM of two positive integers is the