P2158 [SDOI2008] (欧拉函数
题目描述
作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。
现在,C君希望你告诉他队伍整齐时能看到的学生人数。
输入输出格式
输入格式:
一个数N
输出格式:
C君应看到的学生人数。
输入输出样例
输入样例
4
输出样例
9
说明
【数据规模和约定】
对于 100% 的数据,1 ≤ N ≤ 40000
分析:可以发现C仅能看到横纵坐标互质的点。
代码:
1 #include"bits/stdc++.h" 2 #define ci(x) scanf("%d",&x) 3 #define pi(x) printf("%d\n",x) 4 using namespace std; 5 const int N = 1e6 + 5; 6 int n; 7 int ans; 8 int phi[N];//函数值 9 int pri[N]; 10 int cnt;//cnt计数,表示pri[N]中有多少质数 11 void init(){ 12 phi[1] = 1; 13 for(int i = 2; i < N; i ++){ 14 if(!phi[i]){ 15 phi[i] = i-1; 16 pri[cnt ++] = i; 17 } 18 for(int j = 0; j < cnt && 1ll*i*pri[j] < N; j ++){ 19 if(i % pri[j]) phi[i * pri[j]] = phi[i] * (pri[j]-1); 20 else{ 21 phi[i * pri[j] ] = phi[i] * pri[j]; 22 break; 23 } 24 } 25 } 26 } 27 28 int main() { 29 init(); 30 ci(n); 31 ans=3; 32 for(int i=2;i<=n-1;i++) ans+=phi[i]*2; 33 if(n==1) ans=0; 34 pi(ans); 35 36 }