异或不疑惑
http://nynuacm.cn/problem/2023_xbs_06
题意:
现在给出一个长度为 n 的数组,对于全部的子区间,请输出异或和为 2 ^ x (0 <= x <= 16) (意为 2 的 x 次方)的子区间的个数
异或具有前缀和的性质
#define int long long
const int N = 1e6 + 10;
int a[N], b[N * 10];
void solved()
{
int n; cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
a[i] ^= a[i - 1]; //异或前缀和
}
b[0] = 1; //防止漏掉异或为0的情况
int sum = 0;
for(int i = 1; i <= n; i ++)
{
for(int j = 0; j <= 16; j ++)//枚举2的x次方
{
//其实这里可以理解为,等于2^x的话,就加上
//又 因为 a[l]^a[r]=2^x ==> a[l] = a[r]^(2^x)
//所以这里就是在枚举 r和 x,每次加上l出现的次数即可
if(b[1 << j ^ a[i]])
sum += b[1 << j ^ a[i]];
}
b[a[i]] ++;
}
cout << sum << endl;
}
XOR
http://nynuacm.cn/problem/2023_xbs_01
题意:
给定两个正整数 num1 和 num2,请找出满足以下条件的整数x。
1. x 的置位数和 num2 相同
2. x XOR num1 的值 最小
注意: XOR 是按位异或运算,整数的 置位数 指的是二进制表示下 1的 个数。
题目保证, x 是唯一确定的。
void solved()
{
int num1, num2;
scanf("%lld%lld", &num1, &num2);
//求num2的置位数
int cnt = 0;
while(num2)
{
if(num2 % 2) cnt ++;
num2 /= 2;
}
int res = 0;
//因为异或的运算是 : 相同为-, 相异为1, 所以首先要优先考虑高位的1
for(int i = 32; i >= 0; i --)
{
if(cnt && (num1 >> i & 1))
{
cnt --;
res += pow(2, i);
}
}
//如果有多余的1还没有分配完,就优先考虑低位的1进行分配
for(int i = 0; i <= 32; i ++)
{
if(cnt && !(res >> i & 1))
{
cnt --;
res += pow(2, i);
}
}
cout << res << endl;
}