JZOJ_3927. 可见点数 (Standard IO)
Description
ZPS经过长期的努力争取,终于成为了0901班的领操员,他要带领0901班参加广播操比赛。现在0901班的队伍可以看作是一个n*n的点阵,每个人都站在格点上。现在作为领操员的ZPS站(0,0)点,他想知道如果0901班的队伍站齐了,他能看到多少个人的脸(假设每个人的身高相同,体积相同)。
Input
一个正整数n。
Output
ZPS能看到多少个人的脸(当然他是看不到自己的脸的)。
Solution
原问题等价于求多少对(x,y),x与y互质。
线性筛过。
代码
1 var 2 ans:int64; 3 n,nm:longint; 4 v:array [0..100001] of boolean; 5 phi:array [0..100001] of int64; 6 prime:array [0..50001] of longint; 7 procedure try1; 8 var 9 i,j:longint; 10 begin 11 fillchar(v,sizeof(v),false); 12 phi[1]:=1; nm:=0; 13 for i:=2 to 100000 do 14 begin 15 if not v[i] then 16 begin 17 inc(nm); 18 prime[nm]:=i; 19 phi[i]:=i-1; 20 end; 21 j:=1; 22 while (j<=nm) and (i*prime[j]<=100000) do 23 begin 24 v[i*prime[j]]:=true; 25 if i mod prime[j]=0 then 26 begin 27 phi[i*prime[j]]:=phi[i]*prime[j]; 28 break; 29 end; 30 phi[i*prime[j]]:=phi[i]*(prime[j]-1); 31 inc(j); 32 end; 33 end; 34 end; 35 36 procedure main; 37 var 38 i:longint; 39 begin 40 if n=1 then 41 begin 42 write('0'); 43 exit; 44 end; 45 ans:=1; 46 for i:=1 to n-1 do 47 ans:=ans+phi[i]*2; 48 write(ans); 49 end; 50 51 begin 52 try1; 53 readln(n); 54 main; 55 end.