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
Blog by cloud_eve is licensed under CC BY-NC-SA 4.0