• GCD和XOR题解


    由题意

    我们要统计1~N中有多少二元组(a,b)满足gcd(a,b) ==a XOR b


    首先有如下性质

    1.a XOR b >= a-b  (a >= b)

    证明:(给个简单的证明 OI证明都不严谨的)

    在二进制下

      a XOR b :b某一位的1才对答案有影响,如果a那位为1那就相当于减,为0相当于加

      a 减     b: 同样b的某一为的1才对答案影响,且a的那一位不管是0还是1,都是减

    所以 a XOR b 一定 >= a-b

    2. a - b >= gcd( a,b )

    证明:

    设gcd(a,b)=c

    则a=c*x1,b=c*x2(x1,x2互质且大于等于1)x1>=x2

    a - b = c*(x1 -x2)>= c


    所以a XOR b >= a-b >= gcd(a,b)

    而  a  XOR b=gcd(a,b)

    所以a XOR b = a - b = gcd (a,b) 


    到这里解法应该就有很多了,我只分享第一次想到的

    令 gcd(a,b)=d,a=d*x1 ,b=d*x2

    由上述等式得x1-x2=1;

    所以我们外层枚举d,内层枚举b,(a直接得到),然后判断a XOR b 是否等于 a  - b

    代码如下

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=3e7;
     4 int c[N+9];//c[i]表示i与1~i-1中共有多少对满足 
     5 void pre(){
     6     for(int d=1;d<=N;d++){
     7         for(int b=d;b<=N-d;b+=d){
     8             int a=b+d;
     9             if((a^b)==(a-b))c[a]++;
    10         }
    11     }
    12     for(int i=1;i<=N;i++)c[i]+=c[i-1];//求出前缀和 
    13 }
    14 void work(){
    15     int T,n;
    16     scanf("%d",&T);
    17     for(int i=1;i<=T;i++){
    18         scanf("%d",&n);
    19         printf("Case %d: %d
    ",i,c[n]);
    20     }
    21 }
    22 int main(){
    23     pre();
    24     work();
    25     return 0;
    26 } 
  • 相关阅读:
    java实现立方和等式
    java实现立方和等式
    java实现立方和等式
    java实现立方和等式
    java实现立方和等式
    java实现拉丁方块填数字
    java实现拉丁方块填数字
    java实现拉丁方块填数字
    java实现拉丁方块填数字
    IDHTTP用法详解 good
  • 原文地址:https://www.cnblogs.com/zrqlj/p/11413986.html
Copyright © 2020-2023  润新知