【SDOI2008】仪仗队

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P2158


 

最暴力的方法莫过于枚举每个点,看是否能连出一条斜率不与之前重复的线,显然会超时。

我又想着枚举斜率,但本质和枚举点是一样的,还是超时。只有36分。

看到题解,发现原来是自己一个知识点学得不精。枚举斜率判断是否重复其实就是看横纵坐标是否互质,若不互质,那么可以进行约分,说明这个斜率之前出现过。

别人用到了欧拉函数的性质,针对每个数,看看有几个数比他小还和他互质,那么方案数就加上欧拉函数的两倍(欧拉函数只考虑了仪仗队右下半)。

然后注意讨论特殊情况,若n为1,结果为0;否则结果最少是3,然后累加一遍欧拉函数的两倍就可以了(三个点分别是(0,1),(1,0),(2,2))。

 1 #include <cstdio>
 2 
 3 const int maxn = 4e4 + 5;
 4 
 5 int phi[maxn];
 6 
 7 int main() {
 8     int n, cnt = 3;
 9     scanf("%d", &n);
10     if (n == 1) {printf("0");return 0;}
11     for (int i = 1; i <= n; ++i) phi[i] = i;
12     for (int i = 2; i <= n; ++i)
13         if (phi[i] == i) for (int j = i; j <= n; j += i)
14             phi[j] = phi[j]/i*(i - 1);
15     for (int i = 2; i <= n - 1; ++i) cnt += 2 * phi[i];
16     printf("%d", cnt);
17     return 0;
18 }
AC代码

 

posted @ 2018-10-16 11:59  Mr^Kevin  阅读(136)  评论(0编辑  收藏  举报