1 条题解

  • 0
    @ 2025-8-24 21:52:27

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar s_h_y
    **

    搬运于2025-08-24 21:52:27,当前版本为作者最后更新于2017-05-26 22:19:58,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    听说没人证出、、其实dalao们都是懒得证或者懒得说吧。。

    证:当且仅当i+j=2k+1 i+j=2^{k+1} (i,j)=1 (i,j)=1 时,f(i,j)=k f(i,j)=k ;其余情况f(i,j)=0 f(i,j)=0

    一些引理:

    f(λa,λb)=f(a,b)    (λ>0) f(\lambda a,\lambda b)=f(a,b)\ \ \ \ (\lambda>0)

    f(a,b)=f(b,a) f(a,b)=f(b,a)

    必要性证明:当i+j=2k+1 i+j=2^{k+1} (i,j)=1 (i,j)=1 时,f(i,j)=k f(i,j)=k

    不妨设i>j i>j ,因为i,j i,j 互质则有i,j i,j 都是奇数。

    f(i,j)=f(ij,2j)+1=f(ij2,j)+1 f(i,j)=f(i-j,2j)+1=f(\frac{i-j}{2},j)+1

    因为(i,j)=1 (i,j)=1 ,所以(ij,j)=1=(ij2,j) (i-j,j)=1=(\frac{i-j}{2},j)

    这是一个递归的过程,不同的是,i+j=2k+1ij2+j=2k i+j=2^{k+1},\frac{i-j}{2}+j=2^{k}

    故终止时为f(a,b)a+b=21=2 f(a,b)|a+b=2^{1}=2 ,即f(i,j)=f(1,1)+k=k f(i,j)=f(1,1)+k=k

    充分性证明:当i+j2k i+j≠2^{k} (i,j)=1 (i,j)=1 时,f(i,j)=0 f(i,j)=0

    (1)i+j=s1(mod 2) (1)i+j=s≡1(mod\ 2)

    因为(i,j)=1 (i,j)=1 i,j i,j 一奇一偶,

    i>j,f(i,j)=f(ij,2j); i>j,f(i,j)=f(i-j,2j);

    i<j,f(i,j)=f(2i,ji); i<j,f(i,j)=f(2i,j-i);

    因为(ij,2j) (i-j,2j) (2i,ji) (2i,j-i) 仍然满足一奇一偶()(≠)且和为sgcd(ij,2j)\frac{s}{gcd(i-j,2j)}sgcd(2i,ji)(\frac{s}{gcd(2i,j-i)}(不可能为2k)2^{k}),则其永远无法到达终止状态。

    f(i,j)=0 f(i,j)=0

    (2)i+j=2ts0(mod 2) (2)i+j=2^{t}·s≡0(mod\ 2)

    i>j i>j ,则有f(i,j)=f(ij,2j)=f(ij2,j) f(i,j)=f(i-j,2j)=f(\frac{i-j}{2},j)

    ij2+j=i+j2=2t1s \frac{i-j}{2}+j=\frac{i+j}{2}=2^{t-1}·s ,

    故其可以在有限步递归内转换为i+j=s1(mod 2) i+j=s≡1(mod\ 2) 即第(1)(1)种情况。

    f(i,j)=0 f(i,j)=0

    综上得证。

    ###证by shyakocat

    有了这个,我们容易知道公式

    $$Ans=\sum_{i=1,i≡1(mod\ 2)}^{n}\lceil log_{2}(i) \rceil \lfloor \frac{n}{i} \rfloor $$

    就是对每个i考虑1<j<i 1<j<i i+j=2k i+j=2^{k} (i,j)=1 (i,j)=1 ,这样的j显然有且仅有1个。再算上倍数即可。

    由于很多i的答案一样,可以合并下,时间复杂度O(N+log(N)) O(\sqrt[]{N}+log(N))

    var
     n,i,j,a,b,ans:int64;
    
    function min(const a,b:int64):int64;
    begin if a>b then exit(b); exit(a) end;
    
    begin
     read(n);
     i:=1;
     while i<=n do
     begin
      a:=n div i;
      b:=trunc(ln(i)/ln(2)+1e-7);
      j:=min(n div a,int64(1)<<(b+1));
      inc(ans,a*b*((j-i+1+j and 1)>>1));
      i:=j+1
     end;
     write(ans*2)
    end.
    
    • 1

    信息

    ID
    2728
    时间
    1000ms
    内存
    125MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者