第 9 场 小白入门赛 字典树考试

题目:

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值