日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hihoCoder #1872 : Pythagorean triple

發布時間:2024/8/26 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hihoCoder #1872 : Pythagorean triple 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

此題是 2018 年 ICPC Asia Beijing Regional Contest 的 C 題。

題目大意

求斜邊長度不超過 $n$($ n \le 10^9$) 的勾股數的數量。不計兩直角邊的順序,即勾股數 (a, b, c) 和 (b, a, c) 視作同一組。

分析

這是一道頗為經典的計數問題。

請先閱讀維基百科上的 Pythagorean triple 條目。

設斜邊為 $n$ 的勾股數有 $f(n)$ 個。又設斜邊為 $n$ 的本原勾股數有 $g(n)$ 個。于是有
$ f(n) = \sum_{d \mid n} g(d)$ 。

令 $F$ 為 $f$ 的前綴和,令 $G$ 為 $g$ 的前綴和。有
\begin{aligned}
F(n) &= \sum_{i = 1}^{n} f(n) \\
&= \sum_{i = 1}^{n} \sum_{d \mid i} g(d) \\
&= \sum_{i = 1}^{n} G(\floor{n / i})
\end{aligned}

根據 $G$ 的定義,有

\begin{aligned}
G(n) &= \sum_{i = 1}^{n} g(i) \\
&=\sum_{\substack{1 \le x \le n \\ x \text{ is odd} } } \sum_{\substack{1 \le y \le n \\ y \text{ is even}}} [x^2 + y^2 \le n] [\gcd(x, y) = 1] \\
&= \frac{1}{2} \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] [\gcd(x, y) = 1]
\end{aligned}

\begin{aligned}
& \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] [\gcd(x, y) = 1] \\
&= \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] \sum_{d \mid \gcd(x, y)} \mu(d) \\
&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] [d \mid x] [d \mid y] \\
&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le n/d } \sum_{1 \le y \le n } - \sum_{\substack{1 \le i \le n/d \\ di \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [(id)^2 + y^2 \le n] [d \mid y] \\
&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le \sqrt{n}/d } \sum_{1 \le j \le \sqrt{n-(id)^2}/d } - \sum_{\substack{1 \le i \le \sqrt{n}/d \\ di \text{ is odd}} } \sum_{\substack{1 \le j \le \sqrt{n-(id)^2}/d \\ dj \text{ is odd}} } \right) 1 \\
&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le \sqrt{n}/d } \floor{ \frac{\sqrt{n-(id)^2}}ozvdkddzhkzd } - [d \text{ is odd}] \sum_{\substack{1 \le i \le \sqrt{n}/d \\ i \text{ is odd}} } \sum_{\substack{1 \le j \le \sqrt{n-(id)^2}/d \\ j \text{ is odd}} } 1 \right) \\
&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le \sqrt{n}/d } \floor{ \frac{\sqrt{n-(id)^2}}ozvdkddzhkzd } - [d \text{ is odd}] \sum_{\substack{1 \le i \le \sqrt{n}/d \\ i \text{ is odd}} } \floor{\frac{\frac{\sqrt{n-(id)^2}}ozvdkddzhkzd + 1}{2}} \right)
\end{aligned}

TODO:復雜度分析。

Implementation

預處理 $G$ 的前 2000 萬項。

注意:代碼不完整。

int main() {FAST_READcout << fixed << setprecision(1); #ifdef LOCALifstream in("main.in");cin.rdbuf(in.rdbuf()); #endifconst int nax = 1e9 + 1; // println(nax);const int pre_n = 2e7;vl pre_G(pre_n + 1); // pre-calculate some items of Gconst int max_v = sqrt(pre_n);stp(i, 1, max_v + 1, 2) {const int i2 = i * i;const int max_j = sqrt(pre_n - i2);stp (j, 2, max_j + 1, 2) {if (__gcd(i, j) == 1) {pre_G[i2 + j * j]++;}}}rng (i, 1, pre_n + 1) {pre_G[i] += pre_G[i - 1];}const int max_d = sqrt(nax/2);const auto mu = get_mu(max_d);auto G = [&mu, &pre_G, pre_n](int n) { // # of primitive Pythagorean triples with c <= nif (n <= pre_n) return pre_G[n];ll ans = 0;const int max_gcd = sqrt(n / 2);const int tmp = (int)sqrt(n);rng (d, 1, max_gcd + 1) {ll sum = 0;const int max_i = tmp / d;for (int i = 1; i <= max_i; ) {const int arg = int(sqrt(n - sq(i*d))) / d;const int j = int(sqrt(n - sq(arg * d))) / d;sum += (j - i + 1) * arg;if (d & 1) {sum -= (j - i + 1 + (i & 1)) / 2 * ((arg + 1) / 2);}i = j + 1;}ans += sum * mu[d];}return ans / 2;};auto F = [&](int n) { // # of Pythagorean triples with c <= nll ans = 0;for (int i = 1; i <= n; ) {int arg = n / i;int j = n / arg;ans += 1LL * (j - i + 1) * G(arg);i = j + 1;}return ans;};int T; scan(T); rep (T) {int n; scan(n);println(F(n));}#ifdef LOCALcout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n"; #endifreturn 0; }

轉載于:https://www.cnblogs.com/Patt/p/10631987.html

總結

以上是生活随笔為你收集整理的hihoCoder #1872 : Pythagorean triple的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。