哈哈哈其实我是看了题解才来写题解的(嗝
题面
求
[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;
}