题意:
#include<stdio.h>
int main()
{
int n,a[10001];
int T;
int i,j,k;
int ans=0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ans=0;
for(i=0;i<n;++i)
scanf("%d",&a[i]);
for(i=0;i<n;++i)
for(j=0;j<n;++j)
ans+=(a[i]|a[j]);
printf("%d\n",ans);
}
return 0;
}
将以上代码优化不超时。
题意就是这么简单
题解:
很巧妙的算法,利用数位dp的思想将位数分开计算,词穷无法描素,具体看代码。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
typedef long long lld;
#define oo 0x3f3f3f3f
#define maxn 10005
int is_one[maxn][20];//is_one[i][j]第i个数位数为j是1的个数
int sum[maxn];//sum[i]位数为i的和
int a[maxn];
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(sum,0,sizeof sum);
memset(is_one,0,sizeof is_one);
for(int i=1;i<=n;i++)
{
int t=a[i];
for(int j=0;j<16;j++)
{
int r=t%2;
if(r)
{
sum[j]++;
is_one[i][j]=1;
}
t/=2;
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<16;j++)
{
if(is_one[i][j])
ans+=n*(1<<j);
else
ans+=sum[j]*(1<<j);
}
}
printf("%d\n",ans);
}
return 0;
}