「$\mathcal{Darkbzoj}$」神犇和蒟蒻
阿新 • • 發佈:2021-06-30
題目描述
很久很久以前,有一隻神犇叫 \(yzy\)
很久很久之後,有一隻蒟蒻叫 \(lty\)
輸入格式
請你讀入一個整數 \(N,1\leq N\leq 10^9\)
輸出格式
請你輸出一個整數 \(A,B\),模 \(10^9+7\)
\[\begin{aligned} A&=\sum_{i=1}^N{\mu (i^2)}\\ B&=\sum_{i=1}^N{\varphi (i^2)} \end{aligned} \]輸入輸出樣例
輸入
1
輸出
1
1
題解
首先根據 \(\mu\) 函式的性質,容易得到,第一個式子中,只有 \(i=1\) 時才會對答案貢獻 \(1\)
然後考慮如何求 \(B\),首先根據 \(\varphi\) 函式的性質可以得到
\[\varphi(ij)=\frac{\varphi(i)\varphi(j)\gcd(i,j)}{\varphi(\gcd(i,j))} \]那麼原式子可以轉化為
\[\sum_{i=1}^N{\varphi (i)i} \]這個可以套用杜教篩去做,具體證明見杜教篩
程式碼
#include <cstdio> #include <unordered_map> typedef long long ll; using namespace std; const int mod = 1e9 + 7, inv = 166666668; inline int addmod (register int a, register int b) { return a += b, a >= mod ? a - mod : a; } inline int delmod (register int a, register int b) { return a -= b, a < 0 ? a + mod : a; } inline ll mulmod (register ll a, register int b) { return a *= b, a >= mod ? a % mod : a; } int n, cnt; int prime[3000005], phi[3000005], sum[3000005]; bool vis[3000005]; unordered_map <int, int> f; inline void xxs () { phi[1] = sum[1] = 1; for (register int i = 2; i <= 3e6; i ++) { if (! vis[i]) prime[++ cnt] = i, phi[i] = i - 1; for (register int j = 1; j <= cnt && i * prime[j] <= 3e6; j ++) { vis[i * prime[j]] = 1; if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; } phi[i * prime[j]] = phi[i] * phi[prime[j]]; } sum[i] = addmod (sum[i - 1], mulmod (phi[i], i)); } } inline int Getsum (register int l, register int r) { return 1ll * (l + r) * (r - l + 1) / 2 % mod; } inline int Getsum2 (register int n) { return mulmod (mulmod (mulmod (n, n + 1), 2 * n + 1), inv); } inline int F (register int n) { if (n <= 3e6) return sum[n]; if (f[n]) return f[n]; register int ans = Getsum2 (n); for (register int l = 2, r; l <= n; l = r + 1) r = n / (n / l), ans = delmod (ans, mulmod (Getsum (l, r), F (n / l))); return f[n] = ans; } int main () { scanf ("%d", &n), xxs (), printf ("1\n%d\n", F (n)); return 0; }