2190: [SDOI2008]仪仗队
2190: [SDOI2008]仪仗队
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 3609 Solved: 2354
[Submit][Status][Discuss]
Description
作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。 现在,C君希望你告诉他队伍整齐时能看到的学生人数。
Input
共一个数N。
Output
共一个数,即C君应看到的学生人数。
Sample Input
4
Sample Output
9
HINT
【数据规模和约定】 对于 100% 的数据,1 ≤ N ≤ 40000
code
主要求欧拉函数。
1 #include<cstdio> 2 3 const int N = 50000; 4 int phi[N+10],prime[N+10],tot; 5 bool noprime[N+10]; 6 7 void getphi() { 8 for (int i=2; i<=N; ++i) { 9 if (!noprime[i]) prime[++tot] = i,phi[i] = i-1; 10 for (int j=1; j<=tot&&i*prime[j]<=N; ++j) { 11 noprime[i * prime[j]] = true; 12 if (i % prime[j] == 0) {phi[i*prime[j]] = phi[i] * prime[j];break;} 13 phi[i * prime[j]] = phi[i] * (prime[j]-1); 14 } 15 } 16 } 17 int main () { 18 getphi(); 19 int n,ans = 0; 20 scanf("%d",&n); 21 if (n==1) {printf("0");return 0;} 22 for (int i=3; i<=n; ++i) 23 ans += phi[i-1]; 24 ans = ans * 2 + 3; 25 printf("%d",ans); 26 return 0; 27 }
$\sqrt(n)$求法
1 #include<cstdio> 2 3 int getphi(int x) { 4 int ret = 1; 5 for (int i=2; i*i<=x; ++i) { 6 if (x % i == 0) { 7 ret *= (i-1); 8 x /= i; 9 while (x % i == 0) x /= i, ret *= i; 10 } 11 } 12 if (x > 1) ret *= (x - 1); 13 return ret; 14 } 15 16 int main () { 17 int n,ans = 0; 18 scanf("%d",&n); 19 if (n==1) {printf("0");return 0;} 20 for (int i=3; i<=n; ++i) 21 ans += getphi(i-1); 22 ans = ans * 2 + 1 + 2; 23 printf("%d",ans); 24 return 0; 25 }