我们先穷举素数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