[SDOI2008]仪仗队

题目描述

作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。 现在,C君希望你告诉他队伍整齐时能看到的学生人数。

输入输出格式

输入格式:

共一个数N

输出格式: 

共一个数,即C君应看到的学生人数。

输入输出样例

输入样例#1:
4
输出样例#1:
9

说明

【数据规模和约定】

对于 100% 的数据,1 ≤ N ≤ 40000

又是一道欧拉函数的题

本身不难。就是求多少种不同的斜率,也就是小于n互质数,直接套用欧拉函数

线性筛法。

但此题n要先减1,原因:

左下角为(0,0),之所以要这样,是避免斜率为0的直线被作为1/1,1/2,1/3....计算多次

把n-1后对1~n进行处理,得到ans=sum(phi[1~n])
因为x,y可以互换,ans*=2;因为斜率1直线算了两次,所以ans--;

还有两条直线,ans+=2;输出

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 long long phi[40005],ans;
 8 bool mark[40005];
 9 int n,tot,prime[40005];
10 int main()
11 {long long i;
12 long long j;
13     cin>>n;
14     n--;
15     phi[1]=1;
16     for (i=2;i<=n;i++)
17     {
18         if (mark[i]==0)
19         {
20             prime[++tot]=i;
21             phi[i]=i-1;
22         }
23         for (j=1;j<=tot;j++)
24         {
25             long long k=i*prime[j];
26          if (k>n) break;
27          mark[k]=1;
28          if (i%prime[j]==0)
29          {
30              phi[k]=phi[i]*prime[j];
31              break;
32          }
33          else phi[k]=phi[i]*(prime[j]-1);
34         }
35         phi[i]+=phi[i-1];
36         //cout<<i<<' '<<phi[i]<<endl;
37     }
38  cout<<phi[n]*2+1;
39 }

 

posted @ 2017-07-04 14:53  Z-Y-Y-S  阅读(201)  评论(0编辑  收藏  举报