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 } 

 

转载于:https://www.cnblogs.com/zrqlj/p/11413986.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值