洛谷 2158 数论 打表 欧拉函数
2016-11-08 11:21
369 查看
洛谷 2158 数论 递推 欧拉函数 打表找规律
传送门 (https://www.luogu.org/problem/show?pid=2158#sub)其实看到SDOI就有一种不太好的预感,,想当年那个猪国杀,,,呵呵,,
20分暴力
用二维数组维护每个点能否被选择,之后二维枚举每个点,如果没有被选择就选择,并且用它去遮挡其他所有点#include <cstdio> #include <cstring> #include <algorithm> const int maxn = 1000 + 10; int a[maxn][maxn]; int n; int sum; // int ansx[maxn]; // int ansy[maxn]; void update (int x, int y) { int curx = x, cury = y; while (curx <= n && cury <= n) { curx += (x - 1); cury += (y - 1); a[curx][cury] = 1; } } int main () { scanf("%d", &n); for (int i = 1; i <= n; i++) { a[1][i] = 1; a[i][1] = 1; } sum = 2; // ansx[1] = 1; // ansy[1] = 2; // ansx[2] = 2; // ansy[2] = 1; for (int i = 2; i <= n; i++) { for (int j = 2; j <= n; j++) { if (a[i][j] == 0) { a[i][j] = 1; sum++; // ansx[sum] = i; // ansy[sum] = j; update(i, j); } } } printf("%d\n", sum); //for (int i = 1; i <= sum; i++) { // printf("x : %d y : %d\n", ansx[i], ansy[i]); // } return 0; }
正解:
其实这道题的正解是打表打出来的,大概把数字取到10左右就能发现某种性质,x : 1 y : 2 x : 2 y : 1 x : 2 y : 2 x : 2 y : 3 x : 2 y : 4 x : 2 y : 5 x : 2 y : 6 x : 2 y : 7 x : 2 y : 8 x : 2 y : 9 x : 2 y : 10 x : 3 y : 2 x : 3 y : 4 x : 3 y : 6 x : 3 y : 8 x : 3 y : 10 x : 4 y : 2 x : 4 y : 3 x : 4 y : 5 x : 4 y : 6 x : 4 y : 8 x : 4 y : 9 x : 5 y : 2 x : 5 y : 4 x : 5 y : 6 x : 5 y : 8 x : 5 y : 10 x : 6 y : 2 x : 6 y : 3 x : 6 y : 4 x : 6 y : 5 x : 6 y : 7 x : 6 y : 8 x : 6 y : 9 x : 6 y : 10 x : 7 y : 2 x : 7 y : 6 x : 7 y : 8 x : 8 y : 2 x : 8 y : 3 x : 8 y : 4 x : 8 y : 5 x : 8 y : 6 x : 8 y : 7 x : 8 y : 9 x : 8 y : 10 x : 9 y : 2 x : 9 y : 4 x : 9 y : 6 x : 9 y : 8 x : 9 y : 10 x : 10 y : 2 x : 10 y : 3 x : 10 y : 5 x : 10 y : 6 x : 10 y : 8 x : 10 y : 9
由此可见,每个点可取的值与phi[i-1]有关,故使用筛法线性求欧拉函数,之后根据对称性并考虑特殊点,将ans = ans * 2 + 1即为结果
#include <cstdio> #include <algorithm> #include <cstring> const int maxn = 40000 + 100; int phi[maxn], isprime[maxn], prime[maxn]; int n; int tot = 0; long long ans = 0; int main () { scanf("%d", &n); phi[1] = 1; for (int i = 1; i <= n; i++) isprime[i] = 1; for (int i = 2; i <= n; i++) { if (isprime[i]) { tot++; prime[tot] = i; phi[i] = i - 1; } for (int j = 1; j <= tot; j++) { if (i * prime[j] > n) break; isprime[i * prime[j]] = 0; if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; } else { phi[i * prime[j]] = phi[i] * (prime[j] - 1); } } } // for (int i = 1; i <= n; i++) printf("phi[%d] = %d\n", i, phi[i]); for (int i = 2; i <= n; i++) { ans = ans + (long long)phi[i-1]; } ans = ans * 2 + 1; printf("%lld", ans); return 0; }
相关文章推荐
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 洛谷 2158 数论 打表 欧拉函数
- 仪仗队_SDOI2008_洛谷2158_数论
- poj 2478 Farey Sequence(数论:欧拉函数+打表)
- poj 3090 Visible Lattice Points(数论:筛法打表欧拉函数)
- NYOJ 570欧拉函数求和(欧拉函数&&数论入门)
- hihocoder 1298 : 数论五·欧拉函数