GCD和XOR题解

Posted zrqlj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",i,c[n]);
20     
21 
22 int main()
23     pre();
24     work();
25     return 0;
26  

 

以上是关于GCD和XOR题解的主要内容,如果未能解决你的问题,请参考以下文章

题解目录

[题解]noip杂题题解

BZOJ1798题解 Seq维护序列题解 双tag裸线段树

比赛题解 更新ING

Leetcode题解(十八)

USACO 简易题解(蒟蒻的题解)