【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 }