题解 | #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 << ' ';
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 12:11
我最近都有点不想活了,天天早10晚11的,还问我爱不爱她目前的状态别说爱谁了,没扇谁就不错了。是不是大家都是一进节子,只有工作没有爱情了
AzureSkies:在字节的时候找的就是字节的,飞书太适合恋爱人士了,能看到是不是已读,是不是在会议中。简直冥婚好伴侣
投递字节跳动等公司9个岗位
点赞 评论 收藏
分享
喜欢飞来飞去的雪碧在...:可以试一试字节
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

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