CF1582F2 Korney Korneevich and XOR

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] bf[a],j[a+1,V],将 a ⊕ x a\oplus x ax 加入 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值