P6102-[EER2]谔运算【位运算】

正题

题目链接:https://www.luogu.com.cn/problem/P6102?contestId=26472


题目大意

n n 个数的序列 a a ,求
i = 1 n j = 1 n k = 1 n l = 1 n ( a i   o r   a j )   x o r   ( a k   a n d   a l ) \sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n\sum_{l=1}^n(a_i\ or\ a_j)\ xor\ (a_k\ and\ a_l)


题目大意

每一位分开来求
考虑分开来求,若 o r or 为1, a n d and 为0,那么就是求 1 0 至少有一个1的对数*至少有一个是0的对数
o r or 为0, a n d and 为1,那么就是求 0 1 两个都是0的对数*两个都是1的对数
显然这些都很容易求,这里不再多讲


c o d e code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll XJQ=4294967296;
ll n,a[500100],ans;
int main()
{
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	for(ll i=0;i<32;i++){
		ll one=0,o=0,A=0;
		for(ll j=1;j<=n;j++){
			if(a[j]&(1ll<<i)){
				o=(o+j*2-2)%XJQ;
				A=(A+one*2)%XJQ;
				one++;
				o++;A++;
			}
			else o=(o+one*2)%XJQ;
		}
		o%=XJQ;A%=XJQ;
		ans=(ans+o*((n*n%XJQ-A+XJQ)%XJQ)%XJQ*(1ll<<i)%XJQ)%XJQ;
		ans=(ans+A*((n*n%XJQ-o+XJQ)%XJQ)%XJQ*(1ll<<i)%XJQ)%XJQ;
	}
	printf("%lld",ans);
}

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/106321328