From 31be8230f3e2b899a1cd959796c5b4644294d97f Mon Sep 17 00:00:00 2001 From: myoshizumi Date: Sat, 28 Jun 2025 12:15:09 +0900 Subject: [PATCH] =?UTF-8?q?=E7=B9=B0=E3=82=8A=E8=BF=94=E3=81=97=E4=BA=8C?= =?UTF-8?q?=E4=B9=97=E6=B3=95=EF=BC=88Exponentiation=20by=20Squaring?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExponentiationBySquaring.js | 22 ++++++ .../ExponentiationBySquaring.py | 13 ++++ .../Exponentiation by Squaring/README.md | 78 +++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.js create mode 100644 Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.py create mode 100644 Mathematics/Exponentiation by Squaring/README.md diff --git a/Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.js b/Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.js new file mode 100644 index 00000000..cd435a59 --- /dev/null +++ b/Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.js @@ -0,0 +1,22 @@ +const fs = require('fs'); + +// 入力読み取り +const input = fs.readFileSync('/dev/stdin', 'utf8').trim(); +const [A, B, M] = input.split(' ').map(Number); + +// 繰り返し二乗法 +function modPow(a, b, m) { + let result = 1; + a = a % m; + while (b > 0) { + if (b & 1) { + result = (result * a) % m; + } + a = (a * a) % m; + b >>= 1; + } + return result; +} + +// 出力 +console.log(modPow(A, B, M)); diff --git a/Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.py b/Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.py new file mode 100644 index 00000000..8a1d7580 --- /dev/null +++ b/Mathematics/Exponentiation by Squaring/ExponentiationBySquaring.py @@ -0,0 +1,13 @@ +def modpow(a: int, b: int, m: int) -> int: + ans = 1 + while 0 < b: + if b & 1 == 1: + ans = (ans * a) % m + a = (a * a) % m + b >>= 1 + return ans +a: int +b: int +m: int +a, b, m = map(int, input().split()) +print(modpow(a, b, m)) \ No newline at end of file diff --git a/Mathematics/Exponentiation by Squaring/README.md b/Mathematics/Exponentiation by Squaring/README.md new file mode 100644 index 00000000..1e5b708b --- /dev/null +++ b/Mathematics/Exponentiation by Squaring/README.md @@ -0,0 +1,78 @@ +繰り返し二乗法(Exponentiation by Squaring)を用いて `A^B mod M` を高速に計算する JavaScript のコードです。標準入力に対応しています(`fs` モジュールを使用)。 + +--- + +### ✅ JavaScript 解答コード(繰り返し二乗法 + 標準入力対応) + +```javascript +const fs = require('fs'); + +// 入力読み取り +const input = fs.readFileSync('/dev/stdin', 'utf8').trim(); +const [A, B, M] = input.split(' ').map(Number); + +// 繰り返し二乗法 +function modPow(a, b, m) { + let result = 1; + a = a % m; + while (b > 0) { + if (b & 1) { + result = (result * a) % m; + } + a = (a * a) % m; + b >>= 1; + } + return result; +} + +// 出力 +console.log(modPow(A, B, M)); +``` + +--- + +### 🔍 処理の流れ(`2^13 mod M` の例をもとに) + +``` +初期状態: +a = 2, b = 13 → b(2進数) = 1101, m = 7, result = 1 + +1回目: b & 1 = 1 → result = result * a = 1 * 2 = 2 + a = a * a = 4, b = 6 (110) + +2回目: b & 1 = 0 → result unchanged + a = 16, b = 3 (11) + +3回目: b & 1 = 1 → result = 2 * 16 = 32 + a = 256, b = 1 + +4回目: b & 1 = 1 → result = 32 * 256 + a = 65536, b = 0 + +最後に result % 7 = 4 を返す +``` + +--- + +### ✅ 実行例 + +#### 入力: + +``` +2 5 7 +``` + +#### 出力: + +``` +4 +``` + +--- + +### ⏱ 計算量 + +* 時間計算量: `O(log B)` (Bの2進数のビット長に比例) +* 空間計算量: `O(1)` + +---