くろたんく雑記帳

日常とか、わんちゃんとか、機械学習とか、競プロとか、

MENU

Python3で解く AtCoder Beginner Contest 147 D - Xor Sum 4

問題を把握するには、連続したシグマが何を意味しているのか、XORの特性を理解することがポイント。それさえできれば結構単純。自分は桁ごとに考えた。制約としてギリなのでローカル化しないとTLE。もっと工夫できるのかもしれないけど。

目次

概要

問題
1. {\displaystyle n} 個の整数が与えられる。
1.  \displaystyle{\sum_{i=1}^{n-1}\sum_{j=i+1}^{n}(a_i\  XOR\ a_j)}{\displaystyle 10^9+7}で割った余りは?

制約
  • {\displaystyle 2 \leqq n \leqq 3 \times 10^5}
  • {\displaystyle 0 \leqq a_i \lt 2^{60}}

解くときに考えた内容

  • このシグマの連続( \displaystyle{\sum_{i=1}^{n-1}\sum_{j=i+1}^{n}(a_i\  XOR\ a_j)})はどういう意味か?
    • {\displaystyle n=3}の時、i=1から順に代入していくと
    • {\displaystyle a_1 \  XOR\ a_2 +  a_1 \  XOR\ a_3 + a_3 \  XOR\ a_3}ということ
    • {\displaystyle \frac{n(n-1)}{2}}個の重複のない組み合わせでのXORの和ということ
  • XORをどう考えるか
    1. 桁ごとに考える。
      • '^'はPythonでの排他的論理和の論理演算子
      • 1 ^ 1は0
      • 0 ^ 0は0
      • 1 ^ 0は1
      • なので、10となるような状態について各桁で考えればいい。
      • 例えば{\displaystyle a_i}についてbitで考えて特に2桁目について考える。
      • {\displaystyle a_1, a_2, a_3}をbitで考えて2桁目が1とする。(2, 3, 7など) {\displaystyle a_4, a_5}をbitで考えて2桁目が0とする。(4, 1など)
      • 2桁目が1 ^ 0の組み合わせになる数は{\displaystyle 3 \times 2 = 6}となり、bitで2桁目というのは{\displaystyle 2^1}なので、6*2 = 12となる。
      • これを全ての桁で考えればいい。
    2. より一般に考える。
      • {\displaystyle a_i}{\displaystyle d}桁目が1である数を{\displaystyle x}とすると、XORをとって1になる組み合わせ数は{\displaystyle x \times (n-x)}
      • {\displaystyle d}桁目は{\displaystyle 2^{d-1}}である。
      • {\displaystyle x \times (n-x) \times 2^{d-1}}の全ての桁の和が求めるものとなる。

コード

今回はローカル化しないとTLEになってしまうので注意。

def main():
    n = int(input())
    A = [int(x) for x in input().split()]
    ans = 0
    mod = 10 ** 9 + 7
    # 制約がai <= 2**60なので
    for d in range(61):
        # d桁目ごとに考える
        x = 0
        for a in A:
            if (a >> d) & 1:
                x += 1
        ans += x * (n-x) * 2**d
        ans %= mod
    print(ans)

if __name__ == '__main__':
    main()

書籍

アルゴリズムの参考書籍

いわゆる、螺旋本。Aizu Online Judgeの問題を題材に解説されている。自分としては、 Aizu Online Judgeは最近はβ版運用中で、構成がアルゴリズムの項目ごとに問題がタグ付けされているようなイメージで、ここら辺弱いから集中的にやってみようっていう感じでできるので、いいと思っている。(AtCoderもそんな感じのリスト作って欲しい) ただ、この書籍はC++で書かれているのでPythonでやる場合はあくまでもその過程の考え方を参考にし自分で実装する必要がある。(AOJも解いているので、記事にしていこうかなぁ)

最近ポチった書籍

けんちょんさんこと、大槻さんの書籍である、「問題解決力を鍛える!アルゴリズムとデータ構造」 ご本人の記事の中で難易度は、螺旋本ということで初学者でも結構読みやすいのではないかと期待。(というのもけんちょんさんの記事はC++に疎い自分でも、その思考プロセスを学べるくらい丁寧に書かれているので)
投稿時点では、まだ発売前だけど、すでにベストセラー。予約しておかないとすぐ手元に来ないかも!?と思って速攻ポチった。

問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)

問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)

  • 作者:大槻 兼資
  • 発売日: 2020/10/02
  • メディア: 単行本(ソフトカバー)

drken1215.hatenablog.com