牛客寒假算法基础集训营1 C 小a与星际探索

题目链接 

这道题有dp的解法,不过今天看了看 线性基 突然发现这道题可以用线性基

很多情况下,只有有关异或运算和求最值,就可以用到线性基。

这道题的题意就是有n个数,选若干个数使得他们的异或和最大 ,第一个数和最后一个数必须选

唯一需要处理的地方就是从 如果想从 i -> j 则 ai要大于aj ,所以需要把原数组处理一下 

具体如何处理呢? 遍历原数组,当前元素需小于第一个元素且大于最后一个元素。

#include<bits/stdc++.h>
using namespace std;
const int maxn=3000+5;
typedef long long ll;

int a[maxn];
int b[maxn];
int p[20];
int cnt;

void guass()
{
	for(int i=1;i<=cnt;i++)
	{
		for(int j=15;j>=0;j--)
		{
			if(!(b[i]>>j)) continue;  //对线性基的这一位没有贡献
			if(!p[j]) {p[j]=b[i];break;} //选入线性基中
		    b[i]^=p[j];
		}
	}
}
int main(int argc, char const *argv[])
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	if(a[1]<=a[n])
	{
		puts("-1");
		return 0;
	}
	for(int i=2;i<n;i++)
		if(a[i]<a[1]&&a[i]>a[n]) b[++cnt]=a[i];
	guass();
	int ans=a[1]^a[n];
	for(int j=15;j>=0;j--) ans=max(ans,ans^p[j]);
	printf("%d\n", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wzazzy/article/details/88236651