Ehab and the Expected XOR Problem (构造+前缀异或和)
看了题解还是不太懂 , 简单记录一下
题意:给你 n 和 x , 让你在 1 ~ 2^n-1之间寻找最长的一组数 , 使得这组数满足这样一个条件 , 它的
连续子段异或和不为0 或 x.
题解: 1 ~ 2^n-1个数之间 , 任意多个连续组成都有可能是答案,所以首先求a[i]的前缀和。
al⊕al+1⋯⊕ar=bl−1⊕br。
若b[i]前缀和里面有相等的俩个数 , 那么必有某个连续区间异或和为0
若b[i]前缀和里面有某俩个数异或为x , 那么必有某个连续区间异或和为x;
所以 b[i] 必须满足 任意俩俩异或和不为0 或 x 。
b 数组求出来以后 , 原数组为 a[i] = (b[i] ^ b[i-1])--------这里不太懂为甚么
代码开始,直接拿每个数异或x , 并标记-------比如 ,a[1] ^ a[2] = x , 那么标记下a[1] ^x 即标记该数组里有没有a[2]。
是直接去掉异或和为0 和 x 的数吗?
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5;
int vis[maxn];
int main()
{
int n , x , cnt;
scanf("%d %d" , &n , &x);
cnt = (1 << n);
for(int i = 0 ; i < cnt ; i++)
{
if(!vis[i])
{
vis[i^x] = 1;
}
}
vector<int>V;
int ans = 0;
for(int i = 1 ; i < cnt ; i++)
{
if(!vis[i])
{
ans++;
V.push_back(i);
}
}
cout << ans << endl;
int op = 0;
for(int i = 0 ; i < V.size() ; i++)
{
cout << (op^V[i]) << " ";
op = V[i];
}
cout << endl;
return 0;
}