分析
通过观察样例,推理得出结论:改变之后的平方和更大。
认真分析改变两个数的意义:
就是将小的数二进制某些位的1移到大的那个数那里,然后这个位置变为0。
我们也知道,一个数越大,它的平方越大。
我们只需要记录二进制下每一个位置一共有多少个1,然后每次取最大的数,
这样的答案一定是最优的。
code
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#define N 100003
#define ll long long
using namespace std;
ll a[N][23],z[23],sum,ans;
int num[23],n,x,now;
char ch;
void read(int &n)
{
n=0;
ch=getchar();
while((ch<'0' || ch>'9') && ch!='-')ch=getchar();
int w=1;
if(ch=='-')w=-1,ch=getchar();
while('0'<=ch && ch<='9')n=n*10+ch-'0',ch=getchar();
n*=w;
}
int main()
{
z[0]=1;
for(int i=1;i<20;i++)
z[i]=z[i-1]*2;
read(n);
for(int i=1;i<=n;i++)
{
read(x);
for(int j=0;j<20;j++)
if((x&z[j])>0)num[j]++;
}
for(int k=19;k>=0;k--)
for(int i=1;i<=num[k];i++)
a[i][k]=1;
for(int i=1;i<=n;i++)
{
sum=0;
for(int j=0;j<20;j++)
sum+=z[j]*a[i][j];
ans+=sum*sum;
}
printf("%lld\n",ans);
}