【UVA12716】GCD和XOR

题意

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

分析

本题的主要想法就是找到一个沟通gcd(a,b)和a^b的桥梁

  1. a^b≥a-b。口头化证明:假如二进制位上相同,那么都是0,加入二进制位上不同,前者一定是1,后者可能是1(1-0),也有可能借位导致数位减少(0-1)
  2. a-b≥gcd(a,b)。由九章算术·更相减损术可得gcd(a,b)=gcd(a,a-b)=gcd(b,a-b)。显然a-b≥gcd(a,a-b),得证

我们现在已知gcd(a,b)=a^b,根据夹逼法,a^b=a-b=gcd(a,b)=gcd(a,a-b)

换言之,a^b等于a-b,还有取等前提a-b是a的因子

因此我们枚举a-b,求得它的所有倍数,再判断a-b=a^b是否成立。时间复杂度O(N+N/2+N/3+……+N/N)=O(N logN)

注意打好括号,不然等着WA几发吧

代码

  1. #include<bits/stdc++.h>  
  2. using namespace std;  
  3. #define N 30000003  
  4. int t,n;  
  5. int ans[N];  
  6. int main()  
  7. {  
  8.     for(int i=1;i<N;i++)  
  9.     {  
  10.         for(int j=i*2;j<N;j+=i)  
  11.             if((j^(j-i))==i)  
  12.                 ans[j]++;  
  13.         ans[i]+=ans[i-1];  
  14.     }  
  15.     scanf("%d",&t);  
  16.     for(int i=1;i<=t;i++)  
  17.     {  
  18.         scanf("%d",&n);  
  19.         printf("Case %d: %d ",i,ans[n]);  
  20.     }  
  21. }  
原文地址:https://www.cnblogs.com/NSD-email0820/p/9862530.html