D - 88888888
キーワード
解説
の桁数を とおくと、
と書ける。これを で割った余りを求めればよい。 具体的に分数を計算しようとすると、オーバーフローが発生するので、冪乗を都度余りを取りながら計算したいが、割り算が含まれるためそのままでは難しい。そこで、モジュラ逆元を使って計算する。
モジュラ逆元
整数 に対して、 の逆元 は、 を満たす整数 のことである。
と が互いに素である時、 の逆元は必ず存在し、 さらに、 が素数の時、 の逆元は で求めることができる。これはフェルマーの小定理による。
を で割った余りは、 となる。
また、制約から、 であり、このとき は でないことが保証される。
提出コード
- Go
const MOD = 998244353
func main() {
n := readInt()
d := len(strconv.Itoa(n))
ans := n % MOD
ans *= (modPow(modPow(10, d, MOD), n, MOD) - 1) % MOD
ans %= MOD
ans *= modPow(modPow(10, d, MOD)-1, MOD-2, MOD)
ans %= MOD
writeLine(ans)
}
- C++
#define MOD 998244353
ll modPow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1) res = res * x % m;
x = x * x % m;
n >>= 1;
}
return res;
}
int main() {
string n_; cin >> n_;
int k = n_.size();
ll n = stoll(n_);
ll ans = n % MOD;
ans *= (modPow(modPow(10,k,MOD),n,MOD)-1) % MOD;
ans %= MOD;
ans *= modPow(modPow(10,k,MOD)-1,MOD-2,MOD);
ans %= MOD;
cout << ans << endl;
}