题意:Given an integer N(1<N<2^31),you are to calculate ∑gcd(i, N) 1<=i<=N.
分析:数论题的魅力就在于此,一道题就一句简单的描述.
显然,最后的答案肯定是由N的约数组成的,于是我们试着统计每个约数被用了几次.
对于N的一个约数D,有多少个数与N的gcd是D呢?答案是φ(N/D).
于是ans=∑φ(N/D)*D==∑φ(D)*(N/D). (D为N的约数)
效率为O(sqrt(N)).
code:
var p,cnt:array[0..15] of longint;
n,m,num,i:longint;
tmp,ans:extended;
procedure dfs(now:extended; k:longint);
var x,y:longint;
begin
if k>m then
begin
ans:=ans+now*n;
exit;
end;
for x:=0 to cnt[k] do
begin
if x<>0 then now:=now*(1-1/p[k]);
dfs(now,k+1);
if x<>0 then now:=now/(1-1/p[k]);
end;
end;
begin
while not seekeof do
begin
readln(n);
num:=n;
m:=0;
fillchar(cnt,sizeof(cnt),0);
for i:=2 to trunc(sqrt(n)) do
if num mod i=0 then
begin
inc(m);
p[m]:=i;
while num mod i=0 do
begin
inc(cnt[m]);
num:=num div i;
end;
if num=1 then break;
end;
if num>1 then
begin
inc(m);
p[m]:=num;
cnt[m]:=1;
end;
ans:=0;
dfs(1,1);
writeln(ans:0:0);
end;
end.
浙公网安备 33010602011771号