洛谷P2058 仪仗队
题目描述
作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。
现在,C君希望你告诉他队伍整齐时能看到的学生人数。
输入输出格式
输入格式:
共一个数N。
输出格式:
共一个数,即C君应看到的学生人数。
输入输出样例
输入样例#1:
4
输出样例#1:
9
/*开始只是发现i和j互质就能被看见,用了欧几里得算法,但n^2的复杂度确实伤不起啊严重超时只有30*/ #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n; long long ans=0; int gcd(int x,int y) { if(!y) return x; return gcd(y,x%y); } int main() { scanf("%d",&n); for(int i=1;i<n;i++) for(int j=1;j<n&&j<=i;j++) if(gcd(i,j)==1) ans++; if(n==1) printf("0"); else printf("%lld",(ans-1)*2+3); return 0; }
//这是正解 #include<cstdio> int n,phi[40005]; long long ans; void qiu() { phi[1]=1; for(int i=2;i<=n;i++) if(!phi[i]) for(int j=i;j<=n;j+=i) { if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); } } int main() { scanf("%d",&n); qiu(); for(int i=2;i<=n-1;i++) ans+=(long long)phi[i]; printf("%lld",2*ans+3); return 0; }