KeioPC2025-E : Reversed Number Sum

944 types
5 minutes

盆栽をサボっていたので怒られた問題。

問題

正整数 xx に対して、xx の桁を逆順にして leading zero を除いたものを f(x)f(x) とする。入力 n,mn, m に対し、x=110N1f(x)mmod 998244353\sum_{x=1}^{10^N-1} f(x)^m \mathrm{mod}\ 998244353 を求める。

問題リンク

https://atcoder.jp/contests/KeioPC2025/tasks/KeioPC2025_e

解法

適当に実験をすると、結局はx=110n1xmmod 998244353\sum_{x=1}^{10^n - 1} x^m \mathrm{mod}\ 998244353 を求めればよいことが分かる。

S(m,k):=1m+2m+...+(10k)m=i=110kimS(m, k) := 1^m + 2^m + ... + (10^k)^m = \sum_{i=1}^{10^k} i^m として、S(m,n)S(m, n) を求めることを考える。 n109n \leq 10^9 なので愚直には求められないが、m106m \leq 10^6 なので、これを利用して解きたい。S(m,k)S(m, k)Faulhaber's formula を用いて求めることを考えると、Bernoulli Number が分かればよくて、これは二項係数と畳み込みを適切に用いることで O(mlogm)O(m \log{m}) で求まる。(cf. Bernoulli Number - Library Checker)

観察

n=2n = 2 の場合で観察すると、1m,2m,...,10m,11m,...,20m,...,50m,...,99m1^m, 2^m, ..., 10^m, 11^m, ..., 20^m, ..., 50^m, ..., 99^m の総和を求めることになる。便宜上 100m100^m まで足すことを考える。

これらのうち、実際には足されない数は 1010 の倍数であるもので、10m,20m,30m,40m,50m,60m,70m,80m,90m,100m10^m, 20^m, 30^m, 40^m, 50^m, 60^m, 70^m, 80^m, 90^m, 100^m である。これらの和は、

i=110(10i)m=10mi=110im=10mS(m,1)\sum_{i=1}^{10} (10i)^m = 10^m \sum_{i=1}^{10} i^m = 10^m S(m, 1)

より S(m,1)S(m, 1) が求まればよいことが分かる。

x=10,20,...,90x = 10, 20, ..., 90 の時に実際に足されるのは 1,2,...,91, 2, ..., 9 であり、これはそれぞれの値を 1010 で割ったものに等しい。また、x=100x = 100 の時は実際は 11 が足されるが、一旦は 1010 が足されるということにしておく。すると、S(m,2)10mS(m,1)+S(m,1)=S(m,2)(10m1)S(m,1)S(m, 2) - 10^m S(m, 1) + S(m, 1) = S(m, 2) - (10^m - 1) S(m, 1) が求められればよい。

現時点で足されているのは 1m,2m,...,9m,1m,11m,...,2m,21m,...,99m,10m1^m, 2^m, ..., 9^m, 1^m, 11^m, ..., 2^m, 21^m, ..., 99^m, 10^m である。このうち、実際には足されない数は 10m10^m であり、これについて同様に考えると、(10m1)S(m,0)(10^m - 1) S(m, 0) が求められればよい。

よって、この時の答えは

S(m,2)k=01(10m1)S(m,k)=S(m,2)(10m1)k=01S(m,k)S(m, 2) - \sum_{k = 0}^1 (10^m - 1) S(m, k) = S(m, 2) - (10^m - 1) \sum_{k = 0}^1 S(m, k)

結論 (一般解)

以上より、求める答えは S(m,n)(10m1)k=0n1S(m,k)S(m, n) - (10^m - 1) \sum_{k = 0}^{n - 1} S(m, k) である。以降、k=0n1S(m,k)\sum_{k=0}^{n-1} S(m, k) を高速に求める方法を考える。

S(m,n)=1m+1k=0m(m+1k)Bk(10n)m+1kS(m, n) = \cfrac{1}{m + 1} \sum_{k=0}^{m} \binom{m + 1}{k} B_k (10^n)^{m + 1 - k}

をとりあえず畳み込みの形にすると、

S(m,n)=m!a+b=m+1Baa!10nbb!S(m, n) = m!\sum_{a + b = m + 1} \cfrac{B_a}{a!} \cdot \cfrac{10^{nb}}{b!}

であるから、

k=0n1S(m,k)=m!k=0n1a+b=m+1Baa!10kbb!\sum_{k=0}^{n-1} S(m, k) = m! \sum_{k=0}^{n-1}\sum_{a + b = m + 1} \cfrac{B_a}{a!} \cdot \cfrac{10^{kb}}{b!}

このままだと計算量に nn がかかってしまうので、これをなんとかしたい。

数式をいじいじすると、シグマの順番が交換出来て、

k=0n1S(m,k)=m!a+b=m+1Baa!k=0n110kbb!\sum_{k=0}^{n-1} S(m, k) = m! \sum_{a + b = m + 1} \cfrac{B_a}{a!} \cdot \sum_{k=0}^{n-1} \cfrac{10^{kb}}{b!}

あとは等比数列の和の公式を使えば、

k=0n1S(m,k)=m!a+b=m+1Baa!10b(n1)1b!(10b1)\sum_{k=0}^{n-1} S(m, k) = m! \sum_{a + b = m + 1} \cfrac{B_a}{a!} \cdot \cfrac{10^{b(n - 1)} - 1}{b!(10^b - 1)}

となり、k=0n1\sum_{k=0}^{n-1} を消去できた。この値は O(mlogm+mlogn)O(m \log{m} + m \log{n}) で計算できそうなので、計算量の問題は解決した。

S(m,n),10m1S(m, n), 10^m - 1 も高速に求められるので、結果として答えを得られる。

感想

ライブラリ盆栽をサボっていなかったら自前のライブラリでなんとかできたと思うので、ライブラリをちゃんと整えたい。終了後に Nyaan's Library からそのままコピペして提出したら AC 出ました。Nyaan さんいつもありがとうございます。

おわり

おわりです。

Title:KeioPC2025-E : Reversed Number Sum

Author:Oxojo

Link:https://oxojo.dev/posts/keiopc2025-e[Copy]

Last modified :