cf的每个dp题,都有它的特点吧,这个dp就很有特点,但是不难,也没什么好说的..
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=5e3+5;

int dp[N],a[N],w[N],e[N];
bool mp[N];
//dp[i]表示1~i这段最大的值,a[]数组就是题目给定的,然后w[i]存每个值最左边的位子,e[i]存每个值右边的位子.
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<=5000;i++) w[i]=5001,e[i]=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        w[a[i]]=min(w[a[i]],i);//最左边
       // cout<<w[a[i]]<<endl;
        e[a[i]]=max(e[a[i]],i);//最右边
    }
    int st;
    for(int i=1;i<=n;i++)
    {
        dp[i]=dp[i-1];
        int res=0;
        memset(mp,false,sizeof mp);
        st=i;
        for(int j=i;j>0;j--)
        {
          //  cout<<j<<' '<<a[j]<<' '<<e[a[j]]<<' '<<w[a[j]]<<endl;
            if(e[a[j]]>i) break;
           //  if(w[a[j]]<j) continue;
             if(!mp[a[j]]) res^=a[j];
             mp[a[j]]=true;
            if(w[a[j]]<j||j>st) {st=min(w[a[j]],st); continue;}
            dp[i]=max(dp[j-1]+res,dp[i]);
        }
        //cout<<dp[i]<<endl;
    }
    printf("%d\n",dp[n]);
    return 0;
}
/*
5
1558 4081 3591 1700 3232
*/