[UVA-12716] GCD XOR

问题:

a<bN ∀ a < b ≤ N , 求有多少对 (a,b) ( a , b ) 使得 axorb=gcd(a,b) a x o r b = g c d ( a , b )

推导:

满足条件的 (a,b) ( a , b ) 一定有 axorb=gcd(a,b)=ba a x o r b = g c d ( a , b ) = b − a

证明:

  • gcd(a,b)ba g c d ( a , b ) ≤ b − a

    a,b a , b 均为 gcd(a,b) g c d ( a , b ) d的倍数,则 ba b − a 也为其倍数,所以 gcd(a,b)ba g c d ( a , b ) ≤ b − a

  • axorbba a x o r b ≥ b − a
    二进制下一共有4种减法情况:
bac
000
011(带借位)
101
110

可以看出结果总是 a, b 的异或,并且可能带有借位,减小了实际值,所以有 axorbba a x o r b ≥ b − a

  • g=axorb=gcd(a,b) g = a x o r b = g c d ( a , b ) , 则有 g=ba g = b − a

算法:

枚举 ĝ  g ^ ,对其倍数 b̂  b ^ ,得到唯一的 â =ĝ xorb̂  a ^ = g ^ x o r b ^ ,检验是否有 ĝ =b̂ â  g ^ = b ^ − a ^

代码:

#include <bits/stdc++.h>

using namespace std;
const int N_MAX = 3e7 + 10;
int N;

int ans[N_MAX];
inline int est() {
  int cnt = 0;
  for (int c = 1; c <= N; c++) {
    for (int a = c + c; a <= N; a += c) {
      // divisor of a is c
      if ((a - c) == (a ^ c)) {
        cnt++;
        ans[a]++;
      }
    }
  }
  return cnt;
}
int main() {
  N = N_MAX - 1;
  est();
  for (int i = 1; i < N_MAX; i++) ans[i] += ans[i-1];
  int T;
  scanf("%d", &T);
  int ks = 0;
  while (T--) {
    int x; scanf("%d", &x);
    printf("Case %d: %d\n", ++ks, ans[x]);
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值