题意: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.