ABC 147 | D - Xor Sum 4

2020/12/29に公開

問題

https://atcoder.jp/contests/abc147/tasks/abc147_d

解法

愚直にやるとO(N^2)でTLEしてしまう。

N=3のときは以下のようになる。

入力例1のときを考えると以下である。

1ビット目に注目するとXORなのでA_iA_jのどちらかのビットが1でどちらかのビットが0であれば1ビット目が1になる。
ということはA_iの中で1ビット目が0の数と1の数をかけあわせればA_i, A_j (i < j)の組み合わせで1ビット目が1になる組み合わせの数が求められる。
同様に各ビット組み合わせの数を数えてiビット目なら2^{i -1}をかけて足し合わせれば答えとなる。

コード


#include <bits/stdc++.h>

#include <atcoder/all>

using namespace std;
using namespace atcoder;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
const int MOD = 1e9 + 7;

using mint = modint1000000007;

int main() {
  ll n;
  cin >> n;
  vector<int> bits(60);  // iビット目(0-indexed)までの1の個数を入れる
  for (int i = 0; i < n; i++) {
    ll a;
    cin >> a;
    for (int i = 0; i < 60; i++) {
      bits[i] += (a >> i & 1);
    }
  }
  mint ans = 0;
  for (int i = 0; i < bits.size(); i++) {
    ans += mint(2).pow(i) * (bits[i] * (n - bits[i]));
  }

  cout << ans.val() << endl;
}

参考

https://atcoder.jp/contests/abc147/editorial

Discussion