题目
有n个数,任选3个进行异或,求出所有三元组的异或和的和
普通计算是(O(n^3))
但是发现,对于异或的运算,就转换为二进制的运算,把每一个数组转换为二进制,
再拆分,当且仅当$1 ⊕ 1 ⊕1 $和(1⊕0⊕0)时,答案才为1,否则都是0,也就是说,只有这两个情况是由贡献的
把每个数字化为二进制,然后统计每位上1的个数,变成组合数学问题,设cnt[i],表示第i位1的个数,那么答案就是(C_{cnt[i]}^3 + C_{cnt[i]} ^ 1 * C_{n - cnt[i]}^2)
#include<iostream>
using namespace std;
#define ll long long
const int mod = 1000000007;
ll a[1000010];
ll t[64];
ll power(ll a,ll b){
ll res = 1;
while(b){
if(b & 1)res = res * a % mod;
b >>= 1,a = a * a % mod;
}
return res;
}
ll inv(ll x){
return power(x, mod - 2);
}
ll C(ll n, ll m){
if(n < m)return 0;
ll res = 1;
for(ll i = 0; i < m; i++)
res = res * (n - i) % mod, res = res * inv(i + 1) % mod;
return res;
}
int main(){
ll n, m, x;
cin >> n;
for(int i = 0; i < n; i++){
cin >> x;
int j = 0;
while(x){
if(x & 1)t[j]++;
j++,x >>= 1;
}
}
ll sum = 0;
for(int i = 0; i < 64; i++){
sum += (1LL << i) % mod * (C(t[i], 3) + C(n - t[i], 2) * t[i] % mod) % mod;
sum %= mod;
}
cout << sum;
}