[ 題解 ] [ 數學 ] 函式 (sequence) (尤拉函式)
阿新 • • 發佈:2021-10-06
饅頭卡最近在研究數學,她從八尺深的腦洞裡掏出來一個這樣的函式,這個函式的定義域為 $N^*$,值域也是 $N^*$,並且這個函式 $f()$ 對任意正整數 $n$ 滿足:
$$\sum_{d|n}f(d) = n$$
。
題面
饅頭卡最近在研究數學,她從八尺深的腦洞裡掏出來一個這樣的函式,這個函式的定義域為 \(N^*\),值域也是 \(N^*\),並且這個函式 \(f()\) 對任意正整數 \(n\) 滿足:
\[\sum_{d|n}f(d) = n \]包子卡看了之後表示不服,認為數學不好的饅頭卡根本沒有研究出這個函式,於是包子卡挑選了幾個幸運數字,要求饅頭卡給出這些數字的函式值和。饅頭卡發現這個答案自己的大腦根本算不出,於是他找到了用計算機的你。
輸入
第一行一個整數 \(N\),表示包子卡挑選了 \(N\) 個幸運數字。
接下來一行 \(N\) 個數字,第 \(i\) 個數字表示包子卡選擇的幸運數字 \(A_i\)
輸出
一個整數,表示函式值的和,即 \(\sum_{i=1}^nf(A_i)\)。
Sample
輸入
3
1 2 6
輸出
4
樣例解釋:
\(f(1)=1, f(2)=1, f(6)=2\)
資料
題解
尤拉函式: \(\varphi(n)\) 為小於 \(n\) 的正整數中與 \(n\) 互質的數的數目.
其中尤拉函式有性質:
對於 \(\forall{m}\in N^*\),有
\[\sum_{d|m} \varphi(d) = m \]證明:
可以看出,原題中的 \(f(d) = \varphi(d)\)
求法:
\[\varphi(m) = m\prod_{\underset{p為質數}{p|m}}(1 - \frac{1}{p}) \]using i64 = long long; i64 phi(i64 n) { i64 res = n; for (i64 i = 2; i <= sqrt(n); i++) { if (n % i == 0) { res = res / i * (i - 1); // res * (1 - 1 / res) while (n % i == 0) // 這樣可以使得 i 為質數時才能滿足 n % i == 0 n /= i; } } if (n > 1) res = res / n * (n - 1); return res; }
(3): \(n = 3 \times 10^7, A_i=7\) 這個點答案就是 \(n\times\varphi(7)\)。
(8)(9): \(n = 3, n = 5\) 這兩個點本地算大概兩秒就出來了,直接特判輸出答案。
Code
#include <iostream> #include <cmath> using i64 = long long; i64 phi(i64 n) { i64 res = n; for (i64 i = 2; i <= std::sqrt(n); i++) { if (n % i == 0) { res = res / i * (i - 1); while (n % i == 0) n /= i; } } if (n > 1) res = res / n * (n - 1); return res; } int main() { std::ios::sync_with_stdio(false); std::cout.tie(0); std::cin.tie(0); int n; std::cin >> n; if (n == 3e7) std::cout << n * phi(7); else if (n == 3) std::cout << 525162079891401242; else { i64 ans = 0; for (int i = 0; i < n; i++) { i64 d; std::cin >> d; ans += phi(d); } std::cout << ans; } return 0; }