对于每个数字 ai 处理出最左的位置 Lai 和最右的位置 Rai ,然后 dpi 为前i个数字最大的值,对于每一个 Lai=i 的位置计算出来 i到MAX(Rai−Rai) 的异或值,然后更新 dp ,最后 dpn 为最后的答案。
#include<bits/stdc++.h>
using namespace std;
const int N=6000;
int L[N],R[N],a[N],n,ans[N];
int main()
{
scanf("%d",&n);
memset(L,0xff,sizeof(L));
memset(R,0xff,sizeof(R));
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++) scanf("%d",a+i);
for(int i=1;i<=n;i++)
{
if(L[a[i]]==-1)
{
L[a[i]]=i;
for(int j=n;j>=i;j--)
{
if(a[i]==a[j])
{
R[a[j]]=j;
break;
}
}
}
}
int out=0;
for(int i=1;i<=n;i++)
{
ans[i]=max(ans[i],ans[i-1]);
if(L[a[i]]!=i) continue;
int tmp=0,up=R[a[i]],ok=1;
tmp=a[i];
for(int j=i+1;j<=up;j++)
{
if(L[a[j]]<i) {ok=0;break;}
if(R[a[j]]>up) up=R[a[j]];
if(L[a[j]]==j) tmp^=a[j];
}
//printf("%d %d %d %d\n",i,up,ok,tmp);
if(ok)
{
ans[up]=max(ans[up],ans[i]+tmp);
}
}
printf("%d\n",ans[n]);
return 0;
}