Description
ZPS经过长期的努力争取,终于成为了0901班的领操员,他要带领0901班参加广播操比赛。现在0901班的队伍可以看作是一个n*n的点阵,每个人都站在格点上。现在作为领操员的ZPS站(0,0)点,他想知道如果0901班的队伍站齐了,他能看到多少个人的脸(假设每个人的身高相同,体积相同)。
Input
一个正整数n。
Output
ZPS能看到多少个人的脸(当然他是看不到自己的脸的)。
Sample Input
3
Sample Output
5
Data Constraint
40%的数据,n<=1500。 100%的数据,n<=100000。
分析: 某人在原点,所以他的视线可以看做一个正比例函数。显然,对于一个点(x,y),只有当gcd(x,y)=1时才能被看到,否则会被(x/k,y/k) {k=gcd(x,y)} 挡住。显然可以看到的点数等于就是确定i(i<=n)求gcd(i,x)=1 {x<=n}时,x的个数和。我们知道,对于一对(x,y)若被看到,则(y,x)也会被看到,显然关于y=x直对称。这时,我们只需求的解的范围变为 (x<=i),解的个数显然等于φ(i),那么答案就是sum(φ(1)—φ(n))*2+1。由于对称性要乘2,但是(1,1)被算了两遍,要减1,但是也要加上(0,1)和(1,0)这两个点,所以要加1。还有,当n=1是,答案是0哦。
代码:
var phi:array [1..100001] of longint; n,i,j:longint; ans:int64; begin readln(n); if n=1 then begin writeln(0); exit; end; n:=n-1; phi[1]:=1; for i:=2 to n do begin if phi[i]=0 then begin j:=i; while j<=n do begin if (phi[j]=0) then phi[j]:=j; phi[j]:=phi[j] div i*(i-1); j:=j+i; end; end; end; for i:=1 to n do ans:=ans+phi[i]; ans:=ans*2+1; writeln(ans); end.