题目:
4.字典树考试【算法赛】 - 蓝桥云课 (lanqiao.cn)
思路:
我们可以先抛开题目,想一下一个二进制数是 1 1 1 1 1 1 1 1 1 ---> 9个1,题目说(Ai & Aj)所以两个1一个组合, 我们用最笨的方式取枚举 -----> 是 8 + 7+ 6 + 5+ ....... + 1 是36
两两一组,想想X个1如何算呢 ?
是不是应该是 x * (x-1) / 2
换到此题中,两个数相同的数位是1才能为答案做1个贡献,所以我们计算每个数位上1的总数,然后求出结果
我们按位来考虑问题,考虑每个“位”对答案的贡献考虑这个数组的第b位对答案的贡献,显然只有第b位为1才可能对答案有贡献。
任选两个第 b位为1的,即可产生1的贡献。假设有t个第b位为1的。故这一位的贡献为,累加每一位的贡献即可
AC代码:
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
ll arr[N];
int main()
{
cin.tie(0)->ios::sync_with_stdio(false);
// 请在此输入您的代码
int n;
cin >> n;
for(int j=0;j<n;j++)
{
ll x;
cin >> x;
for(int i=0;i<31;i++)
{
//这里要注意需要&1才能把这个位单独取出来
//这里本人忘了&1直接 >> 取 是非常不对的,因为 >> 这个是除2的意思
int bit = x >> i & 1;
if(bit == 1) ++arr[i];
}
}
ll res = 0;
for(int i=0;i<31;i++)
{
//这里是个公式推到res = x * (x-1) / 2;
res += arr[i] * (arr[i]-1) / 2;
}
cout << res;
return 0;
}
标签:题目,入门,int,ll,贡献,小白,答案,位为,字典
From: https://blog.csdn.net/m0_67717626/article/details/137522573