[关闭]
@ZCDHJ 2018-10-03T01:54:52.000000Z 字数 701 阅读 406

SDOI2009 仪仗队

数论


Luogu

题目默认的是以 为左下角,所以一个点 到左下角连线的斜率为 。已知如果两个点到起点的连线斜率相等,就会互相抵挡,所以那些能被看到的点要求在其前面的点连线的斜率没有与它的斜率相等的。那么就是要求 是一个既约分数。等于 互质。但是这个仪仗队的对角线以上以下是对称的,所以只要求出一半的答案,再加上那些一开始就会被看到的点数。最终答案为,注意特判一下 的情况。

  1. #include <iostream>
  2. #include <cstdio>
  3. const int MAXN = 4e4;
  4. int n, ans, tot;
  5. int phi[MAXN | 1], prime[MAXN | 1];
  6. bool vis[MAXN | 1];
  7. int main() {
  8. scanf("%d", &n);
  9. phi[1] = 1;
  10. for(int i = 2; i <= n; ++i) {
  11. if(!vis[i]) {
  12. prime[++tot] = i;
  13. phi[i] = i - 1;
  14. }
  15. for(int j = 1; j <= tot && i * prime[j] <= n; ++j) {
  16. vis[i * prime[j]] = true;
  17. if(i % prime[j] == 0) {
  18. phi[i * prime[j]] = phi[i] * prime[j];
  19. break;
  20. } else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
  21. }
  22. }
  23. for(int i = 2; i < n; ++i) ans += phi[i];
  24. printf("%d\n", ans ? ans * 2 + 3 : 0);
  25. return 0;
  26. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注