2024年第九场蓝桥杯小白赛 字典树考试 知识点:位运算 贡献法

92 阅读1分钟

4.字典树考试【算法赛】 - 蓝桥云课 (lanqiao.cn)

题意解析

题意是说求a数组中任意两个两个元素相与和结果为1的累加和。

思想

image.png 比如a数组是3,1,1,那么它们相与之后如下:

其中①和②的两个1可以相与结果为1,②和③相与为1,①和③相与为1。

总共对答案的贡献是C32=3C3^{2}=3

image.png

再举个例子,像下面这个答案就是C32=3C3^{2}=3+C32=3C3^{2}=3=66

image.png

那么现在我们不知道到底有多少个元素,就是Ca[i]2Ca[i]^{2}

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int a[N];

signed main() {
	int n;
	cin >> n;


	for (int i = 0; i < n; i++) {
		int x;
		cin >> x;

		for (int j = 0; j < 31; j++) {
			a[j] += (x >> j) & 1; //a[j]存放对应位结果为1的结果。
		}
	}

	//算一下对应位是1  a[i],a[j]对这个1的贡献
	//把对应位是1的全部贡献相加
	int sum = 0;
	for (int i = 0; i < 31; i++) {
		sum += a[i] * (a[i] - 1) / 2; //排列组合公式  求a[i],a[i+1]对对应位为1的贡献
	}


	cout << sum << endl;


	return 0;
}