【51Nod 1040】 最大公约数之和

Description

这里写图片描述

Solution

分析题目可以发现,两个数 gcd(a,b)=x ,则等价于 gcd(ax,bx)=1 ,问题就可以转化为满足 gcd(nx,ix)=1 的i的个数,对答案贡献就是个数乘上 gcd(n,i) 。很容易可以想到欧拉函数,因为 φ(n) 是小于等于n的数中与n互质的数的数目, gcd(nx,ix)=1 的i的个数就等于 φ(nx) ,那么x用 n 的时间枚举就好了。

Code

var
    p:array[0..50000] of boolean;
    s:array[0..50000] of longint;
    n,i,j,sum:longint;
    ans:int64;
    pd:boolean;
procedure deal;
var i,j,maxn:longint;
begin
    maxn:=trunc(sqrt(n));
    for i:=2 to maxn do
    begin
        if p[i]=false then
        begin
            inc(s[0]);s[s[0]]:=i;p[i]:=true;
        end;
        for j:=1 to s[0] do
        begin
            if i*s[j]>maxn then break;
            p[i*s[j]]:=true;
            if i mod s[j]=0 then break;
        end;
    end;
end;
function phi(sum:longint):int64;
begin
    phi:=1;
    for j:=1 to s[0] do
        begin
            if sum<s[j] then break;
            pd:=false;
            while sum mod s[j]=0 do
            begin
                sum:=sum div s[j];
                if pd then phi:=phi*s[j] else phi:=phi*(s[j]-1);
                pd:=true;
            end;
        end;
    if sum>1 then phi:=phi*(sum-1);
end;
begin
    readln(n);
    deal;
    for i:=1 to trunc(sqrt(n)) do
    if n mod i=0 then
    begin
        sum:=n div i;
        ans:=ans+i*phi(sum);
        if i<>sum then ans:=ans+sum*phi(i)
    end;
    writeln(ans);
end.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值