异或和之和 异或问题

Posted emcikem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异或和之和 异或问题相关的知识,希望对你有一定的参考价值。

题目
有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;
}

以上是关于异或和之和 异或问题的主要内容,如果未能解决你的问题,请参考以下文章

$Luogu$ $P5514$ $[MtOI2019]$ 永夜的报应

2021-05-13:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,返回arr的最大子数组异或和。

P4735 最大异或和

最大异或和

两区间异或和最大

20170908校内训练