P8438 极寒之地

思路

看了一些 dalao 的题解,没太懂,自己学习了一下。

需要引入一个定义:格雷码

格雷码属于可靠性编码,是一种错误最小化的编码方式,因为虽然二进制码可以直接由数/模转换器转换成模拟信号,但在某些情况,例如从十进制的 3 转换为 4 时二进制码的每一位都要变,能使数字电路产生很大的尖峰电流脉冲。而格雷码则没有这一缺点,它在相邻位间转换时,只有一位产生变化。它大大地减少了由一个状态到下一个状态时逻辑的混淆。
——二进制与格雷码互相转换

引入格雷码有一个极大的优势,就是使用格雷码可以每次只修改一个数

所以,有了格雷码这样的做法,我们可以维护所有子集,用 __builtin_ctz() 来维护当前修改的数位。(主要是我不会 __builtin_ffs() 做这道题)

代码

#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N = 35;
int n, s = 0;
ull a[N], ans, tot;
int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%llu", &a[i]);
	for (int i = 1; i < (1 << n); i++)
	{
		int t = (i) & (-i);
		tot ^= a[__builtin_ctz(t)], s ^= t, ans ^= tot * s;
	}
	printf("%llu\n", ans);
	return 0;
}

自然溢出,用 unsigned long long

posted @ 2024-01-07 16:22  Foiled  阅读(28)  评论(0编辑  收藏  举报