这道题有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;
}