cf1582F2. Korney Korneevich and XOR (hard version)(暴力优化)

发布时间 2023-11-06 19:52:50作者: gan_coder

cf1582F2

对于每种数可以维护一个列表v[x],表示到当前位置,最后一个数小于等于x,能够取到的值,对于当前的数ai,我们可以用v[ai]中的值x与ai异或,来更新v[ai+1],v[ai+2]后面的值。

然后就是有两个优化,每次我们更新完后,都对v[a[i]]清空,因为只有两个相同数之间的数才对后面可能有贡献,前面的已经由前面一个转移完了。

第二个是一个数x假如转移到了v[y],那么也一定转移到了v[y+1],v[y+2],我们可以记录下来。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<unordered_map>
#include<queue>
#include<bitset>
#define A puts("YES")
#define B puts("NO")
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
#define eb(x) .emplace_back(x)
#define lc (o<<1)
#define rc (o<<1|1)
using namespace std;
//typedef __int128 i128;
typedef double db;
typedef long long ll;
const ll mo=1e9+7;
const int N=1e6+5;
const int M=1<<13;
vector<int> v[M+5];
int r[M+5],n,x;
int vis[M+5];
int main()
{
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);

	fo(i,1,M) r[i]=M+1;
	 
	r[0]=0;
	fo(i,1,M) v[i].push_back(0);
	vis[0]=1;
	
	scanf("%d",&n);
	fo(i,1,n) {
		scanf("%d",&x);
		vis[x]=1;
		v[x].emplace_back(x);
		for (int y:v[x]) {
			vis[y^x]=1;
			while (r[y^x]>x) {
				v[r[y^x]].push_back(x^y);
				r[y^x]--;
			}
		}
		v[x].clear();
	}
	
	int ans=0;
	fo(i,0,M) if (vis[i]) ans++;
	printf("%d\n",ans);
	fo(i,0,M) if (vis[i]) printf("%d ",i);
	
	return 0;
}