Simple (笑) とは...
コンテスト中に解けなかったので、どうやったら自然に解けるようになるか整理してみます
問題リンク
A - Simple Math 2
問題概要
を求めよ
( は の整数部分)
M=10で題意を理解してみる
まずは題意を感覚で理解しようとしてみます
maspy さんのおっしゃるように、 で一度考えてみることにします。
mod Mの基礎的なことが非自明に感じる方は、mod 10 の場合を考えるのも良いかもしれません。例えば「ab mod M は a mod M, b mod M から分かる」とかM=10だと知っていますよね。
— maspy (@maspy_stars) January 10, 2021
昨日のAも
「(a^b//10) mod 10 を求めよ」であれば、
「a^b mod 100 があればよい」とすぐに分かる方、増えませんかね。
の部分はとりあえず適当に とかにしといて、 を代入します
これの、
の部分は、
の整数部なので となります。
したがって
となり、 が得られます。
実はこの問題の題意は、 (クソデカ数) を 進数で表したときの下から 桁目を出力せよ と同じなのです。
本当に?
の意味を改めて考えてみます。
これは、 を で割った商です1
と表されるとき、
となります。 商が、あまりが です
整数部分を取る操作は、あまりを無視した商の部分ですので、
です。
次に、 の意味を考えます。
これは読んでそのまま、 を で割ったあまりです。
と表されるとき、
となります。これの、 の部分が です。
さて、求めたいものは でした。
として、まず の式に当てはめます
(↑これの の部分が求めたい答えです)
次に、 、 を使います。
となるので、
となります。
ここで、進数とは、 をこのように分解して表した表現だと言えます。
が 進数における下から桁目、 が 進数における下から桁目... です。
と係数を比較すると、
となります。
したがって、求めたい数値はなので、 を 進数で表したときの下から 桁目を出力せよ と言い換えることができました!
なお、残りの部分は で括れるので として良いです (が本問では無視して良いです)
実装
Pythonが本領発揮できるところでした
以下でACしました!
N,M = map(int,input().split()) ans = pow(10,N,M*M) // M print(ans)
ここで、 pow(10,N,M*M)
は、Pythonでは 「 を で割った余り」を高速に求めてくれます。2
上述の式で、 と表せるところの、
が求まります。
これを // M
で で切り捨て除算することで、求める答えである が得られます。
おわり
simple (笑) とは... という感じだったけど、分かってしまえばなるほど simpleかもです
しかし 300点 緑difficultyとは納得しがたい...
いずれにしても、数式を見て一目で分かるぐらいには慣れていきたい...!