简单的数位dp。
题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=1065
直接上代码了:
#include <cstdio>
#include <cstring>
#include <cmath>
int dp[10005][17]; //dp[i][j]:表示第i个数字转换成二进制后第j位是0还是1
int sum[17]; //sum[j]:表示所有数字转化成二进制后第j位为1的数有多少个
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
int n,r,temp,num;
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&num);
temp=num;
for(int j=0;j<=16 && temp;j++)
{
r=temp%2;
if(r)
{
sum[j]++; //统计第j位为1的数的个数
dp[i][j]=1; //标记第i个数的第j位为1
}
temp/=2;
}
}
int ans(0);
for(int i=0;i<n;i++)
{
for(int j=0;j<=16;j++)
{
if(dp[i][j]) //如果第j位为1,那么与其他任何数进行或运算时结果不变
ans+=n*pow(2,j);
else ans+=sum[j]*pow(2,j); //j位为0.
}
}
printf("%d\n",ans);
}
return 0;
}