LG3812 「模板」线性基 线性基

问题描述

LG3812


题解

线性基是一类擅长解决异或问题的数据结构(也不算数据结构吧...就是一种玄学的东西)

对于数列 \(a\) ,它的线性基 \(d\)出现 \(1\) 的最高位在第 \(i\) 位的数 (这里借用了"帅到报警"的题解)。

构造方法

对于每一个尝试插入的数 \(x\) ,找出它目前为 \(1\) 的最高位 \(pos\)

如果这个时候 \(d_pos\) 已经有了一个数,那么就把 \(x\) 异或上 \(d_pos\) 继续尝试。

否则插入,插入成功后要立刻break

寻找答案

采取贪心思想,只要异或上 \(d_i\) 不会使答案更小,就异或上。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
	x=0;char ch=1;int fh;
	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
	if(ch=='-'){
		fh=-1;ch=getchar();
	}
	else fh=1;
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	x*=fh;
}

#define int long long

int d[63],n;
int a[53],ans;

void add(int x){
	for(int i=51;i>=0;i--){
		if(x&(1ll<<i)){
			if(!d[i]){
				d[i]=x;break;
			}
			x=x xor d[i];
		}
	}
}

void solve(){
	for(int i=50;i>=0;i--){
		if((ans xor d[i])>ans) ans=ans xor d[i];
	}
}

signed main(){
	read(n);
	for(int i=1;i<=n;i++){
		read(a[i]);add(a[i]);
	}
	solve();
	printf("%lld\n",ans);
	return 0;
}
posted @ 2019-10-03 23:37  览遍千秋  阅读(152)  评论(0编辑  收藏  举报