[BZOJ4916]神犇和蒟蒻
阿新 • • 發佈:2018-12-12
求:
\[ \sum_{i = 1}^{n} \mu(i ^ 2) ~~~ \sum_{i = 1}^{n} \varphi(i ^ 2) \\ n \leq 1e9 \]
第一問:我有個寫法可惜這裡空間太小寫不下:
...
printf("1\n");
...
下面我們來考慮第二問:
對於一個素因子\(p\),我們有:
\[ \varphi(p^k) = (p - 1) \times p ^{k - 1}\\ \varphi(p ^ {2k}) = (p - 1) \times p ^ {2k - 1}\\ = (p - 1) \times p ^ {k - 1} \times p^{k}\\ = \varphi(p ^ k) * p ^ k \]
所以:
\[ f(n) = \varphi(n ^ 2) \\\sum_{i = 1}^{n} \varphi(i ^ 2) = \sum_{i = 1}^{n} i \times \varphi(i) \\ \]
構造$g(n) = n $, 有:
\[ (f * g)(n) = \sum_{d | n} d \times \varphi(d) \times \frac{n}{d}\\ = n \sum_{d | n} \varphi(d) = n ^ 2 \]
有:\[1^2 + 2^2 + 3^2+ \dots + n^2 = \frac{n(n + 1)(2n + 1)}{6}\]
然後杜教篩搞一下就可以了。
Codes
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/hash_policy.hpp> using namespace std; #define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i) #define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i) #define clar(a, b) memset((a), (b), sizeof(a)) #define debug(...) fprintf(stderr, __VA_ARGS__) typedef long long LL; typedef long double LD; int read() { char ch = getchar(); int x = 0, flag = 1; for (;!isdigit(ch); ch = getchar()) if (ch == '-') flag *= -1; for (;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48; return x * flag; } void write(int x) { if (x < 0) putchar('-'), x = -x; if (x >= 10) write(x / 10); putchar(x % 10 + 48); } const int Maxn = 3000009, Mod = (int)1e9 + 7; __gnu_pbds :: cc_hash_table <int, LL> Sum; LL isnprime[Maxn], prime[Maxn], tot; LL phi[Maxn], prefix[Maxn]; void init() { phi[1] = 1; rep (i, 2, Maxn - 1) { if (!isnprime[i]) { prime[++tot] = i; phi[i] = i - 1; } for (int j = 1, k; j < Maxn && (k = prime[j] * i) < Maxn; ++j) { isnprime[k] = 1; if (i % prime[j] == 0) { phi[k] = prime[j] * phi[i]; break; }else phi[k] = (prime[j] - 1) * phi[i]; } } rep (i, 1, Maxn - 1) prefix[i] = (prefix[i - 1] + phi[i] * 1ll * i % Mod) % Mod; } LL CalcPhiSquare(int val) { if (val < Maxn) return prefix[val]; if (Sum[val]) return Sum[val]; LL res = val * (val + 1ll) % Mod * (val * 2ll + 1) % Mod * 166666668ll % Mod; for (int l = 2, r; l <= val; l = r + 1) { r = val / (val / l); res -= ((r + 1ll) * r % Mod * 500000004ll % Mod - l * (l - 1ll) % Mod * 500000004ll % Mod + Mod) % Mod * CalcPhiSquare(val / l); (res += Mod) %= Mod; } return Sum[val] = res; } void solve() { int Index = read(); printf("1\n%lld\n", CalcPhiSquare(Index)); } int main() { freopen("BZOJ4916.in", "r", stdin); freopen("BZOJ4916.out", "w", stdout); init(); solve(); #ifdef Qrsikno debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC); #endif return 0; }