ホームページ >バックエンド開発 >C++ >大きな指数を使用して (a^b)%MOD を効率的に計算するにはどうすればよいですか?

大きな指数を使用して (a^b)%MOD を効率的に計算するにはどうすればよいですか?

DDD
DDDオリジナル
2024-10-28 18:57:29523ブラウズ

How to Efficiently Calculate (a^b)%MOD with Large Exponents?

大きな指数を使用した (a^b)%MOD の計算

このコーディングの課題では、タスクは pow( a、b)%MOD。指数 b は非常に大きくなる可能性があります。従来の log(b) 時間計算量法は小さい値には適していますが、 b が C の long long データ型の容量を超えると実用的ではなくなります。

ただし、より効率的なアプローチには、オイラーのトーティエント関数を活用する必要があります。 φ(MOD)。オイラーの定理では、a^φ(MOD)≡1(mod MOD) となります。これは、a のべき乗が a^(b % φ(MOD)) に大幅に削減できることを意味します。

φ(MOD) の計算自体は簡単なタスクではありませんが、整数因数分解方法を使用して達成できます。 。計算後、指数 b を b % φ(MOD) に置き換えることで、計算時間を大幅に短縮できます。

さらなる改良

2008 年に、Schramm は φ が次のことを実証しました。 (b) は、i の範囲が 1 から b である場合、gcd(b, i) の離散フーリエ変換から取得できます。これにより、明示的な因数分解の必要がなくなります。

さらに、カーマイケルの関数 λ(MOD) を使用すると、特に a と MOD が共通の因数を共有する場合に、正しい答えを得ることができます。

コードの実装

次のコード スニペットは C での例として機能します:

<code class="cpp">#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;

ll gcd(ll a, ll b) { return (b == 0) ? a : gcd(b, a % b); }

ll pmod(ll a, ll b, ll mod) {
    if (b == 0) return 1;
    if (b % 2 == 1) {
        return (a * pmod(a, b - 1, mod)) % mod;
    } else {
        ll tmp = pmod(a, b / 2, mod);
        return (tmp * tmp) % mod;
    }
}

int main() {
    ll a, b, mod;
    cin >> a >> b >> mod;
    cout << pmod(a, b % phi(mod), mod) << endl;
    return 0;
}</code>

以上が大きな指数を使用して (a^b)%MOD を効率的に計算するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。