1. 程式人生 > 其它 >cf1582 F1. Korney Korneevich and XOR (easy version)(dp,暴力)

cf1582 F1. Korney Korneevich and XOR (easy version)(dp,暴力)

題意:

給定長為n的陣列a,求a的嚴格上升子序列的異或和的所有可能取值。

n<=1e5, 0<=a[i]<=500

思路:

注意到元素範圍特別小,所有異或和都小於512。

f[i] 表示所有異或和為 i 的上升子列中,末尾元素最小的那個子列的末尾元素。f[i]=INF 表示還沒有子列的異或和為 i。每個 a[i] 可以加到在它之前的、末尾小於 a[i] 的子列的後面,並得到新的異或和 f[j]^a[i],從而更新 f[f[i]^a[i]]

另外注意空的子列也是合法的。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, M = 520, INF = 0x3f3f3f3f;
int n, a[N], f[M];
signed main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);

    memset(f, 0x3f, sizeof f); f[0] = 0; //空的子列
    for(int i = 1; i <= n; i++)
        for(int j = 0; j < M; 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 < M; i++) if(f[i]<INF) ans.push_back(i);
    printf("%d\n", ans.size()); for(int i : ans) printf("%d ", i);

    return 0;
}