[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;
}
posted @ 2020-04-28 10:23  xwmwr  阅读(131)  评论(1编辑  收藏  举报