Solution

要求选出一段子序列使得异或值最大。发现异或运算具有类似于前缀和的性质:由于 的性质,可以快速消除前缀影响。

的异或值,则 即为 的异或值。问题转化为对每个 查询使得异或值最大的 ,字典树实现即可。

需要注意的是,异或运算的优先级低于 ,判断时需要加括号。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5+10;
int n,m,tot=1,pre[N],trie[N<<5][2];
void Insert(int x){
    int y,p=1;
    for(int i=21;i>=0;i--){
        y=(x>>i)&1;
        if(!trie[p][y])
            trie[p][y]=++tot;
        p=trie[p][y];
    }
}
int query(int x){
    int y,p=1,res=0;
    for(int i=21;i>=0;i--){
        y=((x>>i)&1)^1;
        if(trie[p][y])
            p=trie[p][y],res|=(1<<i);
        else if(trie[p][y^1])
            p=trie[p][y^1];
        else
            break;
    }
    return res;
}
int main(){
    cin>>n;
    int x;
    for(int i=1;i<=n;i++)
        cin>>x,pre[i]=pre[i-1]^x;
    int ans=-1,l,r;
    Insert(0);
    for(int i=1;i<=n;i++){
        x=query(pre[i]);
        if(x>ans)
            ans=x,r=i;
        Insert(pre[i]);
    }
    for(int i=r-1;i>=0;i--)
        if((pre[i]^pre[r])==ans){
            l=i+1;
            break;
        }
    cout<<ans<<" "<<l<<" "<<r;
    return 0;
}