大吉大利
题目描述
输入描述:
第一行一个整数n.
第二行n个整数ai.
输出描述:
一个整数表示上述求和式的答案.
可以这样去思考,把一个数拆为二进制去进行求和运算,
例如:
001、010、011、100、101
拿第一个数(001)开始运算,第一位的 1 进行了5次运算;拿第二个数(010)开始运算,第二位的 1 进行了5次运算;拿第三个数(011)开始运算,第二三位的 1 进行了5次运算…
而对于每一位 1 来说,&运算如果跟 1 进行,那么是不变的;所以可以看出只要记录这些数的每一个二进制位 1 的个数,就可以算出答案;
ans= ∑ i = 0 32 ( 1 < < i ) ∗ s u m [ i ] 2 \sum_{i=0}^{32} (1<<i)*sum[i]^2 ∑i=032(1<<i)∗sum[i]2
sum[i]表示所有数 i 进进制位 1 的个数
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100010;
const int M=2000100;
const LL mod=2e9;
int a[N],s[32];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
for(int j=0;j<32;j++){
if((1<<j)&a[i]) s[j]++;
}
}
LL ans=0;
for(int i=0;i<32;i++){
ans+=(1ll*s[i]*s[i]*(1ll<<i));
}
cout<<ans<<endl;
return 0;
}