AtCoder ABC 129 E - Sum Equals Xor(Python)
irisruneです。最近AtCoder ProblemsのRecommendationsがスパルタに感じてきました。
問題
桁DPというヒントを見てしまいましたがほぼ自力です、多分。6/10の記事で実装が重いかと予想していましたが全然重くありませんでした。
import sys import numpy as np MOD = 1000000007 def main(): bits = input() ans = 1 pow3 = 1 for i, b in enumerate(reversed(bits)): if b == '1': ans = ((ans * 2 % MOD) + pow3) % MOD pow3 = (pow3 * 3) % MOD print(ans) main()
アルゴリズムの説明の前に今回使うXORの性質について、となるのはAとB両方が1である(ビット)桁が1つもない場合となります。例えば、の場合はと一致しますがの場合はと一致しません。
逆に言えば今回使うXORの性質はこれ以外ないので、これさえ気付いてしまえばアルゴリズムを考えるのはそう難しくありません。具体的には、
- 0桁のについては答えを1通り()とおく。
- に対し与えられたを一番右の桁から順番に追加する。
- 追加する桁の数字が0ならば、答えは変わらない。
- 追加する桁の数字が1ならば、答えを2倍し、を足す。
という方針で、ほとんど帰納法と言うべきアルゴリズムとなっています。
4.について補足をすると、であることからそれぞれについてが取り得る組み合わせ数を用いてについてが取り得る値の組み合わせ数を計算できます。
ここで、の一番左の桁がどちらか一方のみ1の場合は2通りあるので、についてが取り得る組み合わせ数を2倍した数の組み合わせがあります。
一方、の一番左の桁が両方0の場合は についてが取り得る組み合わせ数を計算することになりますが、各桁について考えるとだけ1の場合、だけ1の場合、両方0の場合の3通りあるので3の累乗で求めることができます。
実装の軽さの割には細かくアルゴリズムを説明するのが大変難しいですね。解くだけならD問題より簡単だとは思いました。
雑記
- 実はTLEを一度起こしていて、3の累乗を求めるのにpow関数を用いたのが原因でした。そもそも余りを求める必要がある問題でpow関数を用いたのもミスですが、計算量もかかるものなんですね。