1. paizaラーニングトップ
  2. レベルアップ問題集
  3. ローリングハッシュメニュー(言語選択)
  4. 問題一覧 Clojure(Beta)編
  5. (問題 2) べき乗計算 Clojure(Beta)編

ローリングハッシュメニューのサムネイル
(問題 2) べき乗計算 Clojure(Beta)編(paizaランク B 相当)

問題にチャレンジして、ユーザー同士で解答を教え合ったり、コードを公開してみよう!

問題

下記の問題をプログラミングしてみよう!

(mod P 上の逆元について)



以降、演算 op にたいして、X op Y を mod P 上で計算した結果 Z になることを X op Y = Z (mod P) と表記します。

ここでは、べき乗計算についてやっていきます。

X ^ Y (mod P) は X を Y 回掛け合わせたものになります。つまり、for文などで繰り返し X を問題 1 と同様にかけていくことで計算が出来ますが、Y が 10 ^ 18 といったように大きくなってしまうと処理に時間がかかりすぎてしまいます。

そこで、2 進数をもとに高速に計算することを考えます。

任意の整数 K に対し、K × K = K ^ 2 (mod P) が成り立ちます。このことより繰り返し掛け合わせていくことにより、X × X = X ^ 2 (mod P)、X ^ 2 × X ^ 2 = X ^ 4 (mod P)、X ^ 4 × X ^ 4 = X ^ 8 (mod P)、... と指数が 2 のべき乗であるものが高速に計算できます。これらを組み合わせることにより任意の Y について、X ^ Y について計算することを考えます。

Y を 2 進数表記で考えます。そのとき Y = y_Ly_{L-1}...y_0 (y_i は 0 か 1)と 2 進数表記で表せたとします。そのとき Y は y_L,y_{L-1},...,y_0 を用いて、Y = y_L × 2 ^ L + y_{L-1} × 2 ^ {L - 1} + ... + y_0 × 2 ^ 0 と 2 のべき乗と y_i の掛け算で表すことが出来ます。

よって、X ^ Y = X ^ {y_L × 2 ^ L × y_{L-1} × 2 ^ {L - 1} × ... × y_{0} × 2 ^ 0} = X ^ {y_L × 2 ^ L} × X ^ {y_{L-1} × 2 ^ {L - 1}} × ... × X ^ {y_0 × 2 ^ 0} (mod P) となります。y_i は 0 か 1 であり、y_i = 0 のときには、X ^ 0 = 1 を、y_i = 1 のときには、X ^ {2 ^ i} をそれぞれ掛け合わせてあげればいいことがわかります。

例として、3 ^ 13 (mod 17) を計算します。3 ^ 1 = 3 (mod 17)、3 ^ 2 = 3 × 3 = 9 (mod 17)、3 ^ 4 = 9 × 9 = 13 (mod 17)、3 ^ 8 = 13 × 13 = 16 (mod 17) と計算でき 13 を 2 進数表記すると 1101 なので、3 ^ 13 = 3 ^ 8 × 3 ^ 4 × 3 ^ 1 = 16 × 13 × 3 = 12 (mod 17) と計算が出来ます。

この方法は繰り返し二乗法とよび、log_2 Y 回程度で計算することが出来ます。10 ^ 18 < 2 ^ 64 により、Y が 10 ^ 18 ととてつもなく大きかったとしても、高速に計算が出来ることがわかります。

では実際に計算してみましょう。

(問題)



素数 P が与えられます。 Q 個のクエリが与えられるので、順番に処理してください。i (1 ≦ i ≦ Q) 番目のクエリは以下の通りです。

  • X_i ^ Y_i (mod P) を出力する。
  • 入力される値

    入力は以下のフォーマットで与えられます。


    P Q
    X_1 Y_1
    X_2 Y_2
    ...
    X_Q Y_Q


  • 1 行目には 2 つの整数 P,Q が与えられます。

  • 1 + i (1 ≦ i ≦ Q) 行目には 2 つの整数 X_i,Y_i が与えられます。

  • 入力は合計で 2 行からなり、入力値最終行の末尾に改行が 1 つ入ります。

  • 入力値最終行の末尾に改行が1つ入ります。
    文字列は標準入力から渡されます。 標準入力からの値取得方法はこちらをご確認ください
    期待する出力

    Q 行で出力してください。
    i (1 ≦ i ≦ Q) 行目には i 番目のクエリの答えを出力してください。

    条件

    すべてのテストケースにおいて、以下の条件をみたします。


    • 10 ^ 8 ≦ P ≦ 2 × 10 ^ 9

    • 1 ≦ Q ≦ 200000

    • 1 ≦ X_i,Y_i ≦ P - 1 (1 ≦ i ≦ Q)

    • P は素数

    入力例1

    998244353 3
    10 10
    734 765
    777 999

    出力例1

    17556470
    65071411
    99508285

    問題一覧へ戻る

    ページの先頭へ戻る