From 0fe5697686270d672e8d954eb12b90722b620fbc Mon Sep 17 00:00:00 2001 From: myoshizumi Date: Sun, 20 Jul 2025 15:25:48 +0900 Subject: [PATCH 1/2] =?UTF-8?q?atcoder=20B28=20-=20Fibonacci=20Easy=20(mod?= =?UTF-8?q?=201000000007)=20=E3=83=95=E3=82=A3=E3=83=9C=E3=83=8A=E3=83=83?= =?UTF-8?q?=E3=83=81=E6=95=B0=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Fibonacci number/atcoder/B28/B28.go | 130 ++++++++++++ .../Fibonacci number/atcoder/B28/B28.js | 86 ++++++++ .../Fibonacci number/atcoder/B28/B28.php | 126 ++++++++++++ .../Fibonacci number/atcoder/B28/B28.py | 124 +++++++++++ .../Fibonacci number/atcoder/B28/B28.ts | 90 ++++++++ .../Fibonacci number/atcoder/B28/README.md | 192 ++++++++++++++++++ 6 files changed, 748 insertions(+) create mode 100644 Mathematics/Fibonacci number/atcoder/B28/B28.go create mode 100644 Mathematics/Fibonacci number/atcoder/B28/B28.js create mode 100644 Mathematics/Fibonacci number/atcoder/B28/B28.php create mode 100644 Mathematics/Fibonacci number/atcoder/B28/B28.py create mode 100644 Mathematics/Fibonacci number/atcoder/B28/B28.ts create mode 100644 Mathematics/Fibonacci number/atcoder/B28/README.md diff --git a/Mathematics/Fibonacci number/atcoder/B28/B28.go b/Mathematics/Fibonacci number/atcoder/B28/B28.go new file mode 100644 index 00000000..0b640d26 --- /dev/null +++ b/Mathematics/Fibonacci number/atcoder/B28/B28.go @@ -0,0 +1,130 @@ +// 以下に、**Go 1.20.6** によるフィボナッチ数列の第 N 項を $10^9+7$ で割った余りを高速に求める実装を提示します。 + +// --- + +// ## ✅ 実装方針 + +// | 項目 | 内容 | +// | ----- | ----------------------- | +// | 時間計算量 | `O(N)`(1ループ) | +// | 空間計算量 | `O(1)`(配列不使用) | +// | 型の明示 | すべての関数と変数に明確な型を付与 | +// | メモリ効率 | スタック上の変数3つのみ使用 | +// | 入出力 | `fmt.Scan` を使用(高速 & 標準) | + +// --- + +// ## 🧮 Go (1.20.6) 実装コード + +package main + +import ( + "fmt" +) + +const MOD int = 1_000_000_007 + +/** + * fibonacciMod は、フィボナッチ数列の第 n 項を MOD(10^9+7) で割った余りを返します。 + * + * @param n int フィボナッチ数列の項番号(3 <= n <= 10^7) + * @return int 第 n 項を 10^9 + 7 で割った余り + */ +func fibonacciMod(n int) int { + if n == 1 || n == 2 { + return 1 + } + + var a, b int = 1, 1 // a: F(n-2), b: F(n-1) + for i := 3; i <= n; i++ { + next := (a + b) % MOD + a = b + b = next + } + return b +} + +func main() { + var n int + _, err := fmt.Scan(&n) + if err != nil { + panic("入力エラー") + } + + result := fibonacciMod(n) + fmt.Println(result) +} + +// ## ✅ 処理ステップの解説(図解) + +// ``` +// 初期状態: +// a = 1 (F₁) +// b = 1 (F₂) + +// i = 3: +// next = (a + b) % MOD = 2 +// a = 1, b = 2 + +// i = 4: +// next = (1 + 2) % MOD = 3 +// a = 2, b = 3 + +// ... + +// i = N: +// 結果は b(Fₙ) +// ``` + +// --- + +// ## 📈 性能と制約対応 + +// | 性能項目 | 内容 | +// | ------ | ------------------------- | +// | 時間計算量 | O(N) | +// | 空間計算量 | O(1)(変数3つのみ) | +// | 実行時間 | N = 10^7 でも 0.2 ~ 0.5 秒程度 | +// | メモリ使用量 | 数十KB程度 | +// | 対応制約 | `3 ≤ N ≤ 10^7` 完全対応 | + +// --- + +// ## 🧪 テスト例 + +// ### 入力 + +// ``` +// 6 +// ``` + +// ### 出力 + +// ``` +// 8 +// ``` + +// --- + +// ## ✅ 実行方法 + +// ```bash +// go run main.go +// ``` + +// または、標準入力からの入力付きで: + +// ```bash +// echo 8691200 | go run main.go +// ``` + +// --- + +// ## ✅ 補足:高速化を希望する場合 + +// * `O(log N)` の **行列累乗法** や **Doubling法** による高速フィボナッチ計算も可能です。 +// * ご希望があれば図付きでご案内します。 + +// --- + +// 以上が Go (1.20.6) による、シンプルかつ高性能なフィボナッチ計算実装です。必要があれば高速バージョンの提供も可能です。 diff --git a/Mathematics/Fibonacci number/atcoder/B28/B28.js b/Mathematics/Fibonacci number/atcoder/B28/B28.js new file mode 100644 index 00000000..275df77b --- /dev/null +++ b/Mathematics/Fibonacci number/atcoder/B28/B28.js @@ -0,0 +1,86 @@ +// 以下は、指定された条件(Node.js / `fs` を使った標準入力 / 実行時間とメモリ制限内)に従い、**フィボナッチ数列の第 N 項を $10^9+7$ で割った余り**を計算するJavaScriptコードです。 + +// --- + +// ### ✅ 実装のポイント + +// * 定数 `MOD = 1_000_000_007` を使って **オーバーフローを防止**。 +// * **繰り返し計算(O(N))** を使用(メモリを抑えつつ高速)。 +// * `BigInt` は使いません(今回は必要ありません)。 +// * **配列を使わず2変数だけ保持**して、**メモリ効率を最大限に向上**。 + +// --- + +// ### 📦 JavaScript (Node.js 18.16.1) 実装 + +// ```javascript +// 入力処理(標準入力) +const fs = require('fs'); +const input = fs.readFileSync('/dev/stdin', 'utf8').trim(); +const N = parseInt(input); + +// フィボナッチ数列の第 N 項を MOD で割った余りを返す +// @param {number} n - 求めたい項の番号 +// @return {number} - フィボナッチ数列の第 n 項の MOD(10^9+7)余り +function fibonacciMod(n) { + const MOD = 1_000_000_007; + if (n === 1 || n === 2) return 1; + + let a = 1; // a(n-2) + let b = 1; // a(n-1) + for (let i = 3; i <= n; i++) { + const next = (a + b) % MOD; + a = b; + b = next; + } + return b; +} + +// 出力 +console.log(fibonacciMod(N)); +// ``` + +// --- + +// ### 📈 実行性能 + +// * **時間計算量**: `O(N)` (ループ1回) +// * **空間計算量**: `O(1)` (変数2つのみ使用) +// * **実行時間目安**: + +// * `N = 10^7` でも **数百ms〜1秒未満**(Node.jsのループ処理高速) +// * **メモリ使用量**: + +// * 数十KB程度(**配列未使用**) + +// --- + +// ### 🧪 テスト例 + +// #### 入力: + +// ``` +// 6 +// ``` + +// #### 出力: + +// ``` +// 8 +// ``` + +// #### 入力: + +// ``` +// 8691200 +// ``` + +// #### 出力: + +// ``` +// 922041576 +// ``` + +// --- + +// さらに高速化を求める場合、`O(log N)` の**行列累乗**法に切り替えることも可能です。希望があればその版もご提供できます。 diff --git a/Mathematics/Fibonacci number/atcoder/B28/B28.php b/Mathematics/Fibonacci number/atcoder/B28/B28.php new file mode 100644 index 00000000..6b7d73d0 --- /dev/null +++ b/Mathematics/Fibonacci number/atcoder/B28/B28.php @@ -0,0 +1,126 @@ +