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;
}
posted @ 2021-11-20 13:29  Horb7  阅读(34)  评论(0编辑  收藏  举报