[EER2]谔运算 口胡
哈哈哈其实我是看了题解才来写题解的(嗝
题面
求
\[\sum_{i=1}^n \sum_{j=1}^n \sum_{k=1}^n \sum_{l=1}^n (a_i \; or \;a_j) \quad xor \quad (a_k \; and \; a_l)
\]
\(n\) 的规模为 \(5e5\)。
分别统计二进制下的每一位 \(p\) 在这个和式里出现了多少个 \(1\) , 记为 \(sum_p\), 则答案为
\[\sum_p sum_p*2^{p}
\]
如何快速计算 \(sum_p\)?
简单来说就是给出布尔值 \(a、b、c、d\) 分别等于 \(1\) 的情况数, 求 \((a \; or \;b) \quad xor \quad (c \; and \; d)\) 等于 \(1\) 的情况数。
然后就没了。
只能过样例的代码(比赛结束交不了qwq)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+15;
#define li long long
#define ui unsigned int
ui n;
ui a[maxn];
ui C[55];
int main()
{
scanf("%u", &n); for(int i=1;i<=n;++i) {
scanf("%u",&a[i]);
for(int j=0;j<=31;++j) if((a[i]>>j)&1) ++C[j];
}
ui ans = 0ll;
for(int i=0; i<=31; ++i) {
ui lef1 = C[i]*C[i] + C[i]*(n-C[i]) + (n-C[i])*C[i];
ui lef0 = (n-C[i])*(n-C[i]);
ui rig1 = C[i]*C[i];
ui rig0 = (n-C[i])*(n-C[i]) + C[i]*(n-C[i]) + (n-C[i])*C[i];
ui all1 = lef0*rig1 + lef1*rig0;
ans += all1*(1<<i);
}
cout<<ans;
}