bzoj 2190 线性生成欧拉函数表
首先我们知道,正方形内个是对称的,关于y=x对称,所以只需要算出来一半的人数
然后乘2+1就行了,+1是(1,1)这个点
开始我先想的递推
那么我们对于一半的三角形,一列一列的看,假设已经求好了第I-1列的,那么第I列加上
之后,不会影响前I-1列能看见的人,那么第I列一共加上I个人,设坐标是(I,Y),
我们可以发现如果gcd(I,Y)<>1的时候这个点是看不见的,因为横纵坐标存在约数,也就是
前面有一个整点点和这个点还有原点在同一直线上(三角形相似),那么我们要找第I列I,Y互质的
点,也就是和I互质的点的个数,也就是phi(i),那么就不用递推了,我们每个I都要累加phi,也就是
生成1-n-1的欧拉函数表就行了(n-1是因为(0,0)点算第1列,我就在这儿WA了一次。。。)
/************************************************************** Problem: 2190 User: BLADEVIL Language: Pascal Result: Accepted Time:28 ms Memory:696 kb ****************************************************************/ //By BLADEVIL var i, j :longint; n :longint; phi, mindiv :array[0..40100] of longint; prime :array[0..40000] of longint; ans :int64; begin read(n); for i:=2 to n do begin if mindiv[i]=0 then begin mindiv[i]:=i; inc(prime[0]); prime[prime[0]]:=i; phi[i]:=i-1; end; for j:=1 to prime[0] do begin if prime[j]*i>n then break; if i mod prime[j]<>0 then phi[i*prime[j]]:=phi[i]*(prime[j]-1) else phi[i*prime[j]]:=phi[i]*prime[j]; mindiv[prime[j]*i]:=prime[j]; if i mod prime[j]=0 then break; end; end; phi[1]:=1; for i:=1 to n-1 do ans:=ans+phi[i]; ans:=ans*2+1; writeln(ans); end.