Kazun の競プロ記録

競技プログラミングに関する様々な話題を執筆します.

AtCoder Beginner Contest 293 E問題 Geometric Progression

問題

atcoder.jp

提出解答

atcoder.jp

問題の概要

 \displaystyle \sum_{i=0}^{X-1} A^i M で割った余りを求めよ.

制約

  •  1 \leq A,M \leq 10^9
  •  1 \leq X \leq 10^{12}

解法

 \displaystyle S_x:=\sum_{i=0}^{x-1} A^i とおく. このとき, 求めるべきは  S_X である.

 x=1 のとき  \displaystyle S_1=\sum_{i=0}^0 A^i=1 となる.

 x 3 以上の奇数のとき,  S_x=S_{x-1}+A^{x-1} である *1.

 x が偶数のとき

 \begin{align*}
S_x
&=\sum_{i=0}^{x-1} A^i \\
&=\sum_{i=0}^{\frac{x}{2}-1} A^i+\sum_{i=\frac{x}{2}}^{x-1} A^i \\
&=\sum_{i=0}^{\frac{x}{2}-1} A^i+\sum_{j=0}^{\frac{x}{2}-1} A^{\frac{x}{2}+j} \\
&=\sum_{i=0}^{\frac{x}{2}-1} A^i+A^{\frac{x}{2}} \sum_{j=0}^{\frac{x}{2}-1} A^j \\
&=\left(1+A^{\frac{x}{2}} \right) \sum_{i=0}^{\frac{x}{2}-1} A^i \\
&=\left(1+A^{\frac{x}{2}} \right) S_{\frac{x}{2}}
\end{align*}

となる.

よって,

 S_x=\begin{cases} 1 & (x=1) \\
S_{x-1}+A^{x-1} & (x \geq 3, x: \text{odd}) \\
\left(1+A^{\frac{x}{2}} \right) S_{\frac{x}{2}} & (x: \text{even}) \end{cases}

となる.

ここで,  S の添字は  2 回行うと必ず半分以下になる. そして,  A^x については繰り返し二乗法を利用することで,  O(\log x) 時間で求めることができる.

従って, この関係式を利用することにより,  S_X O((\log X)^2) 時間で求められることができる.

*1:この関係式は  x が偶数のときでも成り立つ.