CF 1582F1. Korney Korneevich and XOR (easy version)
CF 1582F1. Korney Korneevich and XOR (easy version)
题意
给定长度为 \(n\) 的序列 \(a\) ,我们可以选择任意一个升序的子序列 \(a_{i_1}, a_{i_2}, ..., a_{i_k}\) ,求出他们的 \(xor\) 值。
求出所有这样的 \(xor\) 值。
\(1 \le n \le 10^5, 0 \le a_i \le 500\) 。
题意
由于我们找出的形成 \(xor\) 值的子序列必须是升序的,因此判断每个元素的时候,我们需要知道所有前面比它小的值。
注意 \(a_i \le 500\) ,因此我们所求出的 \(xor\) 值一定小于 \(512\) 。
我们用对暴力判断前面比他小的值这里做优化,使用 \(512\) 个桶记录形成每个异或答案的序列的最小值(贪心,这样可以使后面的元素有机会和这个序列异或)。
Code
/* 终点是一切概率的结束,也是一切期望的开始 */
#include <bits/stdc++.h>
#define rep(i, x, y) for(int i = x; i <= y; i++)
#define per(i, x, y) for(int i = x; i >= y; i--)
#define forr(x, s) for (auto x : s)
#define all(a) begin(a),end(a)
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
#define pb emplace_back
#define int long long
using namespace std; using PII = pair<int, int>;
const int N = 10000, M = 6000, mod = 998244353, INF = 0x3f3f3f3f;
void solve ()
{
int n; cin >> n;
vector<int> a(n); forr(&x, a) cin >> x;
vector<int> b(512, INF); // 桶,表示构成每个异或答案的序列末尾的最小值
b[0] = 0; // 由于可以选择空序列,所以要添加0
for (int x : a)
{
b[x] = min(b[x], x); // 自己作为序列末尾
for (int j = 0; j < 512; j ++ ) // 枚举每个异或答案值
{
if (b[j] < x) // 可以构成递增序列
b[x ^ j] = min(b[x ^ j], x);
}
}
vector<int> ans;
for (int i = 0; i < 512; i ++ )
if (b[i] != INF) ans.pb(i);
cout << ans.size() << endl;
for (int i = 0; i < ans.size(); i ++ ) cout << ans[i] << " \n" [i == ans.size() - 1];
}
signed main ()
{
cout.tie(0)->sync_with_stdio(0);
// int _; for (cin >> _; _--; )
solve();
return 0;
}