CF1582F2 Korney Korneevich and XOR
由于值域较小,考虑在值域上搞事情。
记集合 f [ i ] f[i] f[i] 包含当前以 a a a 结尾的子序列的可能异或值,满足 a < i a<i a<i。
每读入一个 a a a,便对于 b ∈ f [ a ] , j ∈ [ a + 1 , V ] b \in f[a],j\in[a+1,V] b∈f[a],j∈[a+1,V],将 a ⊕ x a\oplus x a⊕x 加入 f [ j ] f[j] f[j]。
考虑到每次即值域后缀集合加点,便对于每个异或出来的值 p p p,记 m x p mx_p mxp 表示未添加 p p p 的最小集合编号。
标记一下每次异或出来的值即可,时间复杂度 O ( n + V 2 ) \mathcal O(n + V^2) O(n+V2)。
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
#define ha putchar(' ')
#define he putchar('\n')
inline int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = x * 10 + c - '0', c = getchar();
return x * f;
}
inline void write(int x)
{
if(x < 0)
{
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
const int _ = 1 << 13;
int n, mx[_], ans = 1;
vector<int> d[_];
bool vis[_];
signed main()
{
n = read();
vis[0] = 1;
for(int i = 1; i < _; ++i) d[i].push_back(0), mx[i] = _ - 1;
for(int i = 1, x; i <= n; ++i)
{
x = read();
for(int v : d[x])
{
int p = v ^ x; ans += !vis[p], vis[p] = 1;
while(mx[p] > x) d[mx[p]--].push_back(p);
}
d[x] = {};
}
write(ans), he;
for(int i = 0; i < _; ++i)
if(vis[i]) write(i), ha;
return 0;
}