Description
作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。现在,C君希望你告诉他队伍整齐时能看到的学生人数。
Input
共一个数N
Output
共一个数,即C君应看到的学生人数。
Sample Input
4
Sample Output
9
HINT
【数据规模和约定】
对于 100% 的数据,1 ≤ N ≤ 40000
题解
如图建系:
注意到“某人被挡住”即某人的坐标可以约分。
我们先不考虑坐标轴上的点。
那么先算出$1~n-1$这个范围内所有满足题意的点,先考虑$y<x$
$$\sum_{x=1}^{N-1}\sum_{y=1}^{x-1}[gcd(x,y)=1]$$
转化为
$$\sum_{x=1}^{N-1}φ(x)$$
做完之后我们将算出来的$ans×2$得到$y>x$的情况。
由于没考虑坐标轴上的点,我们再将$ans+2$,
由于没考虑$φ(1)=1$,我们再将$ans+1$。
1 #include<map> 2 #include<set> 3 #include<ctime> 4 #include<cmath> 5 #include<queue> 6 #include<stack> 7 #include<cstdio> 8 #include<string> 9 #include<vector> 10 #include<cstdlib> 11 #include<cstring> 12 #include<iostream> 13 #include<algorithm> 14 #define LL long long 15 #define RE register 16 #define IL inline 17 using namespace std; 18 const int N=40000; 19 20 int n; 21 22 bool isprime[N+5]; 23 int prime[N+5],top; 24 int phi[N+5]; 25 IL void Pre(); 26 27 int main() 28 { 29 scanf("%d",&n); 30 Pre(); 31 LL ans=0; 32 for (RE int i=1;i<n;i++) 33 ans+=phi[i]; 34 printf("%lld\n",ans*2+3); 35 return 0; 36 } 37 38 IL void Pre() 39 { 40 for (RE int i=2;i<=n;i++) 41 { 42 if (!isprime[i]) phi[i]=i-1,prime[++top]=i; 43 for (RE int j=1;j<=top&&i*prime[j]<=n;j++) 44 { 45 isprime[i*prime[j]]=1; 46 if (!(i%prime[j])) {phi[i*prime[j]]=phi[i]*prime[j];break;} 47 else phi[i*prime[j]]=phi[i]*phi[prime[j]]; 48 } 49 } 50 }
时间: 2024-09-29 14:16:50