geam1113’s diary

主にAtcoderのコンテストの備忘録を書きます。AtCoder緑と水色を行ったり来たりしています。

ABC186E Throne

問題

 

Baby-step giant-stepによる解法とWeb公式解説の理解メモ

 

 

公式解説の理解

公式解説

 

A,B,Md=gcd(A,B,M)で割って良い理由

A' \leftarrow A/d,\ B' \leftarrow B/d,\ M' \leftarrow M/dとします。

 

Ax \equiv B\ mod\ M

を変形し、

Ax-B \equiv 0\ mod\ M

とします。

Ax-BMの倍数となる必要があります。

Mの倍数であるとは、約数としてMを含むということです。

ここで、

dA'x-dB'=d(A'x-B')

となるので、

A'x-B'M'の倍数なら、dM'を約数に含むこととなり、Ax-BMの倍数となります。

したがって、元の問題を

A'x\equiv B' \ mod\ M'

という問題に帰着させることができます。

 

gcd(A',M') \neq 1の時に解なしになる理由

A'x\equiv B'\ mod\ M'

という問題は、

A'x+M'y = B'

を満たす整数x,yを求める問題とみなせます。この問題に解が存在するための必要十分条件は、

B'gcd(A',M')で割り切れること

です。しかし、単にこの条件を見るだけでは、gcd(A',M')が必ずしも1である必要はありません。

 

では、なぜ解を持つ時に必ずgcd(A',M')=1が成り立つことかを考えてみます。

 

d'=gcd(A,M)とします。

(1) d=d'のとき

すなわちBd'を約数に持つ場合です。

この時、A',M'は共通の約数が無くなって、gcd(A',M')=1となります。

この時、当然B'を割り切ることができ、解を持ちます。

 

(2) d\neq d'のとき

このとき、Bd'に含まれる約数のうちの1つを持ちません。

それをd''とおくと、gcd(A',M')=d'' \neq 1となります。

B'd''を約数に持たないので、割り切れず、解なしとなります。

 

以上より、解を持たない時、gcd(A',M')\neq 1が示されました。

 

自分が疑問に感じたのはこれだけです。

次に、Baby-step giant-stepの考え方による解法を書いておきます。

 

Baby-step giant-stepによる解法

コンテスト当時にtwitterで言及されていたので、解いてみました。

 

この問題の解は非負整数nを用いて、

nK+S\equiv 0\ mod\ N

を求める問題に帰着されます。

 

ここで、m=\lceil \sqrt{M} \rceilとおきます。

nmで割った商iと余りjを用いて、n=im+jとおけます。

0\leq i\lt m,\ 0\leq j\lt m

なので、

(im+j)K+S\equiv 0 \ mod\ N
を満たすi,jの組をO(m^2)(=O(N))で全探索できますが、これだと間に合いません。

 

そこで、式を変形して、

jK+S\equiv -imK\ mod\ N

とすると、jを含む左辺は右辺のiの影響を受けず一定となります。

従って、予めj = 0, 1, ..., mについて、

jK+S\ mod\ N

を計算し、ハッシュマップなどに記録しておくことで、

i=0,1,..,mについて、

-imk\ mod\ N

と等しいものがあるかをO(1)で判定できるようになり、全体でO(m)(=O(\sqrt{N}))となります。

 

実装上、

Sgcd(N,K)で割った余りが0でない時は解なしとなり、これは予め判定しておく必要がある。

jK+S\ mod\ Nで同値なものが複数ある場合、jが最小のもののみ記録する。

という点に気をつけます。

 

計算量は公式解説より劣りますが、あまり深く考えなくて良いのは楽だと思いました。

提出コード