欧拉函数 || [SDOI2008]仪仗队 || BZOJ 2190 || Luogu P2158
题解:
显然除了(1,1),(0,1),(1,0)三个点外,对于其他点(x,y)只要满足gcd(x,y)==1就可以被看到 然后这些点是关于y=x对称的,所以直接考虑一半就可以 考虑下半部分的点(x,y)(y<x),对于每个x,小于x且与x互质的y就是答案数
于是就转化为了欧拉函数,2~N的欧拉函数和*2+3(前面那三个点)就是答案了。
代码:
1 #include<cstdio> 2 using namespace std; 3 const int maxn=4e4+5; 4 int N,phi[maxn],v[maxn],Prim[maxn],num_prim=0,ans=0; 5 inline void Get_Prime(int n){ 6 for(int i=2;i<=n;i++){ 7 if(v[i]==0){ 8 v[i]=i; 9 phi[i]=i-1; 10 Prim[++num_prim]=i; 11 } 12 for(int j=1;j<=num_prim;j++){ 13 if(v[i]<Prim[j] || i*Prim[j]>n) break; 14 v[i*Prim[j]]=Prim[j]; 15 if(i%Prim[j]==0) 16 phi[i*Prim[j]]=phi[i]*Prim[j]; 17 else phi[i*Prim[j]]=phi[i]*(Prim[j]-1); 18 } 19 } 20 } 21 int main(){ 22 scanf("%d",&N); 23 N--; 24 Get_Prime(N); 25 for(int i=2;i<=N;i++) ans+=phi[i]; 26 ans=ans*2+3; 27 if(N==0) ans=0; 28 printf("%d\n",ans); 29 return 0; 30 }
By:AlenaNuna