【hpu oj 1014: 985的数学难题 [思维] 】

点击打开链接


【hpu oj 1014: 985的数学难题 [思维] 】_第1张图片



题解:


/*
x^y+x&y==x|y
考虑二进制的每一位对结果的影响
比如1101、1001、1010进行上述运算
则可发现:
从右到左每一位上有1的个数记为
cnt[0]~cnt[3]分别为2、1、1、3
因为或运算除了0|0==0
其余都为1也就是0|1+1|1.
依次看二进制末尾有多少数贡献了1,再根据位运算的性质进行计数即可。
*/
#include
#include
#include
#define M 100009
using namespace std;
int a[M];
int cmp(int A,int B)
{
	return A>B;	
}
int main()
{
	int t,i,n;
	while(~scanf("%d",&t))
	{
		while(t--)
		{
			long long sum=0;
			scanf("%d",&n);
			for(i=1;i<=n;i++)
			{
				scanf("%d",&a[i]);
				sum+=a[i];
			}
			sum*=(n-1);
			sort(a+1,a+n+1,cmp);
			long long m=1,ans;
			while(a[1])
			{
				ans=0;
				for(i=1;i<=n;i++)
				{
					if(a[i]==0)
						break;
					if(a[i]&1)
						ans++;
					a[i]>>=1;
				}
				sum+=(ans*(n-ans)+(ans-1)*ans/2)*m*2;
				m<<=1;
			}
			printf("%lld\n",sum);
		}
	}
	return 0;
}



你可能感兴趣的:(思维)