我们先穷举素数p
然后令y>x 这样问题就是求这个gcd(x,y)=p  (1<=x<y=n)
不难发现必须y=kp k∈N* 当y=p时,易知个数为φ(1)
当y=2p 个数为φ(2),……当k最大为[n/p]时,个数为φ([n/p])
这不就是求欧拉函数的前缀和
因此我们要用筛法把φ(1~n)求出来弄一下前缀和即可

 1 var p:array[0..1000010] of longint;
 2     f:array[0..10000010] of int64;
 3     v:array[0..10000010] of boolean;
 4     n,i,j,t:longint;
 5     ans:int64;
 6 
 7 begin
 8   readln(n);
 9   fillchar(v,sizeof(v),false);
10   f[1]:=1;
11   for i:=2 to n do
12   begin
13     if not v[i] then
14     begin
15       inc(t);
16       p[t]:=i;
17       f[i]:=i-1;
18     end;
19     for j:=1 to t do
20       if p[j]*i<=n then
21       begin
22         v[p[j]*i]:=true;
23         if i mod p[j]=0 then
24         begin
25           f[i*p[j]]:=f[i]*int64(p[j]);
26           break;
27         end
28         else f[i*p[j]]:=f[i]*int64(p[j]-1);
29       end
30       else break;
31   end;
32 
33   for i:=1 to n do
34     f[i]:=f[i-1]+f[i];
35 
36   for i:=1 to t do
37     ans:=ans+(f[n div p[i]]-1)*2+1; //注意x=y
38   writeln(ans);
39 end.
40 
41  
View Code

 

posted on 2014-12-11 21:07  acphile  阅读(135)  评论(0编辑  收藏  举报