努力才快乐
题目描述
给定n个整数,依次为a1,a2,…,an。
求∑i=1n∑j=1n(ai&aj) “&”是二进制的与运算符。
输入
第一行一个整数n.
第二行n个整数ai.
输出
一个整数表示上述求和式的答案.
错误思路
我是直接把输入的ai 存起来,然后使用for 循环进行求和,发现时间复杂度太高,算不了。然后想了好久也不知道。然后参考其他的大佬思路
大佬思路
计算每一个输入数二进制的1在那个位置,举个例子 3 和 1 那就等于0001&0011 那也等于 0001&(0010+0001)根据与运算的规则,0010 与0001 是为0 的,以此类推,就可以整个计算的过程。
代码
#include<iostream>
using namespace std;
typedef long long ll;
ll n;
ll a[10004];
ll w;
ll maxn = 0;
int max(ll a, ll b)
{
return a > b ? a : b;
}
int main()
{
//输入数
cin >> n;
for (int i = 1; i <= n; i++)
{
int ans = 0;//1在多少位
cin >> w;
while (w)
{
++ans;
if (w & 1) a[ans]++;
w >>= 1;//向右移动一位
}
maxn = max(ans,maxn);//得出最高为是多少
};
ll sum = 0;
for (int i = 1; i <= maxn;i++)
{
sum += (a[i] * a[i]) << (i - 1);
};
cout << sum;
return 0;
}
总结
在碰到大的数运算的时候,想到位运算,不要直接使用暴力,我的整体算法思路都不是很好,自己还是需要不断加强锻炼。