公约数

Description

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

Data Constraint

对于30%的数据满足n<=1000
对于60%的数据满足n<=10^5
对于100%的数据满足n<=10^7

Solution

这道题是结论题。。。
首先我们要知道一些结论:

1. a xor b=c 等价于 a xor c=b 这点很显然啊
2. gcd(a,b)<=a-b (a>b) 这点你可以想一下辗转相除,或者更相减损术,就懂了
3. a xor b>=a-b (a>b) 1 xor 1=0,1-1=0,相等;1 xor 0=1,1-0=1,相等;0 xor 1=1,0-1退位,异或打;0 xor 0=0,0-0=0,相等。所以异或要大于等于减法。

然后根据第一点,我们就可以拿60分。O(n)枚举c(a和b的gcd),O(log n)枚举i,a=c*i,b=a xor c,然后O(log n)判断a和b最大公约数是不是c就好了。这样是O(n log2 n)的
再看看第二点和第三点结论,很显然可以得到a-b=c (c=gcd(a,b)),所以跟60分一样枚举c,再枚举i,a=c * i,b=a-c,很明显gcd(a,b)=c(自己想一想就好了,a=i * c,b=(i-1)*c),所以只用判断a xor b是否等于c就好了,这样就少掉了一个log。

Code

Var
    n:Longint;
    Ans:Int64;

Function Gcd(x,y:Longint):Longint;
Begin
    If y=0 Then Exit(x);
    Gcd:=Gcd(y,x Mod y);
End;

Procedure Work();
Var
    a,b,g,i:Longint;
Begin
    For g:=1 To n Do
        For i:=3 To n Div g Do
        Begin
            a:=g*i; b:=a-g;
            If a Xor b=g Then Inc(Ans);
        End;
End;

Begin
    Readln(n);
    Work();
    Writeln(Ans);
End.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值