GCD和XOR

声明

这并不是一篇讲述gcd与xor有什么神奇关系的文章,只是一道题目名而已。

题意

给定一个正整数n,在[1,n]的范围内,求出有多少个无序数对(a,b)满足gcd(a,b)=a xor b。

思考时间

…….
…….
…….
…….
…….

题解

我们来证明两个比较显然的命题,
对于两个正整数a,b且a大于b。
①a xor b a-b
②a-b gcd(a,b)
首先证明①:
根据xor的运算我们可以得到 p,q{0,1} ,有p xor q p-q
然后我们将a,b两个数转化为二进制,则有
a-b= i=1(aibi) ,( ai,bi{0,1}
a xor b= i=1 ( ai xor bi ),( ai,bi{0,1}
结合上面命题显然成立。
②:
设a=pd,b=qd,(p,q)=1,那么a,b的最大公约数即为d。
p-q=d(p-q),
若p=q,那么此时(p,q)=p,也即p和q的最大公约数不为1,矛盾,舍去。
若p大于q时,显然成立p-q=d(p-q) > d

进入正题

那么如果有a xor b=gcd(a,b),那么就有a xor b=a-b=gcd(a,b),也就是说gcd(a,b)=a-b。那么这样一来,题目就很简单了,我们可以类比线筛的方法,枚举一个a,b的gcd,然后再枚举一个a,算出b,判断一下是否有a xor b=c即可。

诡异的复杂度

1/n+2/n+……+n/n=nlogn,恕我学术不精,不会证。
代码:

const
        maxn=1000000+5;
var
        sum,ans:array[0..maxn] of longint;
        i,j,k,a,b,c,t,n:longint;
begin
        readln(t);
        k:=1;
        while t<>0 do
        begin
                dec(t);
                readln(n);
                if (sum[n]=0)and(k<=n) then
                begin
                        for c:=k to n do
                        begin
                                 a:=c*2;
                                 while a<=maxn do
                                 begin
                                        b:=a-c;
                                        if a xor b=c then
                                                inc(ans[a]);
                                        inc(a,c);
                                 end;
                        end;
                        for i:=k to n do
                        begin
                                sum[i]:=sum[i-1]+ans[i];
                        end;
                        k:=n;
                        writeln(sum[n]);
                end
                else
                        writeln(sum[n]);
        end;
end.

the end

由于我的水平有限,难免会有些写错的地方,希望大家批评指正,多多包容,thank you for your patience.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值