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.