LuoGu: SP21615 NAJPWG - Playing with GCD
SPOJ: NAJPWG - Playing with GCD
莫反当然可以搞,但是加上数论分块后 $O(\sqrt n)$ 的单次询问的复杂度比较卡。
$$
\begin {array}{c}
& \displaystyle \sum _ {i = 1} ^ n \sum _ {j = i} ^ n [(i, j) > 1] \\
\Longrightarrow & \displaystyle \sum _ {i = 1} ^ n \sum _ {j = 1} ^ {i - 1} [(i, j) > 1] \\
\end {array}
$$
也就是交换了 $i$ $j$ 的枚举顺序。
注意到
$$
\displaystyle \sum _ {i = 1} ^ {j - 1} [(i, j) = 1] = \varphi (j)
$$
故答案为
$$
\sum _ {i = 1} ^ n i - \varphi (i)
$$
预处理后,$O(1)$ 后回答。
查看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <cstdio> using namespace std; const int N = 1e5 + 10; bool vis[N]; int cnt, primes[N], low[N], phi[N], s[N]; void init() { phi[1] = 1; low[1] = 1; for (int i = 2; i < N; i++) { if (!vis[i]) { primes[++cnt] = i; phi[i] = i - 1; low[i] = i; } for (int j = 1; j <= cnt && i * primes[j] < N; j++) { vis[i * primes[j]] = true; if (i % primes[j] == 0) { low[i * primes[j]] = low[i] * j; if (low[i] == primes[j]) phi[i * primes[j]] = phi[i] * (phi[primes[j]]); else phi[i * primes[j]] = phi[i / low[i]] * phi[primes[j] * low[i]]; phi[i * primes[j]] = phi[i] * primes[j]; break; } low[i * primes[j]] = primes[j]; phi[i * primes[j]] = phi[i] * phi[primes[j]]; } } for (int i = 1; i < N; i++) s[i] = s[i - 1] + i - phi[i]; } int main() { init(); int T; scanf("%d", &T); for (int i = 1, a; i <= T; i++) { scanf("%d", &a); printf("Case %d: %d\n", i, s[a]); } return 0; }
|