题解 | #F1. Korney Korneevich and XOR (easy version)#

F1. Korney Korneevich and XOR (easy version)

题意

给定长度为n的序列a[n],对于a[n]中的任意上升子序列(不连续),其XOR值都加入答案的集合中,求这个答案集合。

首先,任意两个a,b512a, b \le 512ab512a \bigoplus b \le 512 ,这样最后答案的集合大小不会超过512,这提示我们可能是一个f(1e5,512)f(1e5, 512) 的DP. 设状态方程为 f(i,j) f(i, j)表示前ii个元素中,异或值为jj的序列的末位元素最小值。于是得到状态转移方程:

f(i,ja[i])=f(i1,ja[i])f(i,j \bigoplus a[i])=f(i-1,j \bigoplus a[i])

a[i]ja[i] \ge j,有f(i,ja[i])=min(f(i1,ja[i]),a[i])f(i,j \bigoplus a[i])=min(f(i-1,j \bigoplus a[i]), a[i])

这个方程可以优化成一维,且不影响正确性

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int a[N];
int f[N];
int main() {
    int n; cin >> n;
    for(int i = 1; i <= n; i ++) {
        cin >> a[i];
    }
    memset(f, 0x3f, sizeof f); f[0] = 0;
    for(int i = 1; i <= n; i ++) {
        for(int j = 0; j < 512; j ++) {
            if(f[j] < a[i]) {
                f[j ^ a[i]] = min(f[j ^ a[i]], a[i]);
            }
        }
    }
    vector<int> ans;
    for(int i = 0; i < 512; i ++) {
        if(f[i] != 0x3f3f3f3f) ans.push_back(i);
    }
    cout << ans.size() << endl;
    for(auto &it: ans) cout << it << ' ';
}

全部评论

相关推荐

05-29 09:02
门头沟学院 Java
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务