ながめも

競技プログラミングについて

パナソニックプログラミングコンテスト(AtCoder Beginner Contest 186)E - Throne

E - Throne

問題へのリンク

 S + m \times K \equiv 0 \pmod Nを満たす最小の整数 mを求めよ。

拡張ユークリッドの互除法による逆元計算

まず、与式を m \equiv -S \times K^{-1} \pmod Nと変形することで K^{-1} \pmod Nが求まれば、問題を解くことができるとわかります。

ここで、 \pmod Nにおける Kの逆元の存在条件は、 N Kが互いに素であることです。

NとKが互いに素のとき

 N Kが互いに素のとき、 Kの逆元 K^{-1} \pmod Nは、拡張ユークリッドの互除法(extGCD)によって求まります。

拡張ユークリッドの互除法による逆元の求め方

 aK + bN = 1を満たす整数 (a, b)をextGCDによって求め、この式を \pmod Nの式に変形すると、 aK = 1 \pmod Nとなることから、 K^{-1} = aつまり、aが Kの逆元になっています。

NとKが互いに素でないとき

 N Kが互いに素ではない場合、 Kの逆元 K^{-1} \pmod Nは存在しません。では、今回の問題を解くことはできないのでしょうか。サンプルをみればわかる通り、そういうわけではありません。

 N Kが互いに素でないなら、互いに素にしたくなります。 N Kを、 g = gcd(N, K)で割った結果をそれぞれ N^{\prime}, K^{\prime}とおくと、 N^{\prime} K^{\prime}は互いに素です。

これら N^{\prime} K^{\prime}をextGCDにかけることで、 K^{\prime -1} \pmod {N^{\prime}}を求めることができました。

与式に戻り N,K,Sをそれぞれ N^{\prime}, K^{\prime}, \frac{S}{g}に置き換え、

 \frac{S}{g} + m \times K^{\prime} \equiv 0 \pmod {N^{\prime}}

とすれば、 \frac{S}{g}が整数、すなわち S gの倍数である場合に、先ほどextGCDによって求めた K^{\prime -1} \pmod {N^{\prime}}を用いて mを求めることができます。

 S gの倍数ではない場合、解はありません。

実装

提出へのリンク

long long extGCD(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long x2, y2;
    long long d = extGCD(b, a%b, x2, y2);
    x = y2;
    y = x2 - (a / b) * y2;
    return d;
}
long long mod_inv(long long a, long long m){
    ll x, y;
    ll d = extGCD(a, m, x, y);
    if(d != 1)return -1;
    if(x < 0)x += m; 
    return x;
}
long long safe_mod(long long a, long long m){
    return (a%m+m)%m;
}
void solve(){
    ll N, S, K;
    cin >> N >> S >> K;
    ll g = gcd(N, K);
    ll inv = mod_inv(K/g, N/g);
    if(S % g != 0){
        cout << -1 << endl;
    }
    else{
        ll ans = S/g * (-inv);
        ans = safe_mod(ans, N/g);
        cout << ans << endl;
    }
}

中国剰余定理

 S + m \times K \equiv 0 \pmod N

という式から、以下のような連立合同式を考えます。

{\displaystyle 
\begin{eqnarray}
  \left\{
    \begin{array}{l}
      x \equiv 0 \pmod N \\
     x \equiv S \pmod K
    \end{array}
  \right.
\end{eqnarray}
}

中国剰余定理によって、この連立方程式を解きます。(解がない場合もあります。その場合は、今回は-1を出力して終わりです)。

このとき、 N Kの最小公倍数を lcmとすると、

 x \geq Sの場合、  m = \frac{x-S}{K}

 x \lt Sの場合、  m = \frac{x+lcm-S}{K}

となります。

中国剰余定理で求まる xは、周期 lcmであり、その間に唯一のものであるから、当然今回の解に不適切なものも出てくる( S未満など)ので、その場合は、一個先の解を使えばよい( lcmを足しているのはそのためである)。

実装

提出へのリンク