0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

繰り返し二乗法と逆元をKotlinで実装

Last updated at Posted at 2024-10-26

はじめに

KotlinでAtCoderに取り組んでいます。

Kotlin標準のMath.powはdouble or float型にて計算するため扱いにくいのでLong型対応のものを実装しました。(参考)

modを考慮しないpow

繰り返し二乗法により実装します。

fun pow(xx: Long, nn: Long): Long {
    var res = 1L
    var x = xx
    var n = nn
    while (n > 0) {
        if (n % 2 == 1L) res *= x
        x *= x
        n = n.shr(1)
    }
    return res
}

modを考慮したpow

掛け算のたびにmodをとります。

fun modPow(xx: Long, nn: Long, mod: Long): Long {
    var res = 1L
    var x = xx % mod
    var n = nn
    while (n > 0) {
        if (n % 2 == 1L) res = res * x % mod
        x = x * x % mod
        n = n.shr(1)
    }
    return res
}

フェルマーの小定理による逆元の算出

modPowを使用します。

fun modInv(x: Long, mod: Long): Long {
    return modPow(x, mod - 2, mod)
}

拡張Euclidの互除法による逆元の算出

fun modInv(xx: Long, mod: Long): Long {
    var x = xx
    var b = mod
    var u = 1L
    var v = 0L
    while (b > 0) {
        val t = x / b
        x -= t * b
        x = b.also {b = x}
        u -= t * v
        u = v.also {v = u}
    }
    u %= mod
    if (u < 0) u += mod
    return u
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?