您的位置:首页 > 其它

JZOJ4446【HNOI模拟】B

2016-04-21 18:55 337 查看

Description



Solution

∪and,∩or,上and下or。

一看到and和or就要想到数里面01的变幻。

我们发现a=a and b其实就是b在某位为0的情况下把0换到a去,b=a or b其实就是a在某位为1的情况下把1换到b去,其实就是a与b的交换。

那么现在问题就是变成转移0和1,导致最后的平方和最大。

考虑二元组,看看是交换优还是不交换优。

现在假设a>b,如果a需要把(k+1)位的1转移b去。

转移后的平方和为(a−2k)2+(b+2k)2

原来的平方和是a2+b2

比较一下那个大,两式相减得2k+1(a−b),因为a>b,所以上式≥0,所以转移了更优。

那么只有把当前位的所有1集中在一起就好了。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
typedef long long ll;
const int maxn=100007;
using namespace std;
ll i,j,k,l,t,n,m,ans;
int b[maxn];
int main(){
scanf("%lld",&n);
fo(i,1,n){
scanf("%lld",&k);
fo(j,0,20){
if(k&(1<<j)){
b[j]++;
}
}
}
fo(i,1,n){
k=0;
fo(j,0,20){
if(b[j]){
b[j]--;
k+=(1<<j);
}
}
ans+=k*k;
}
printf("%lld\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: