CF-282-E-Trie
282-E 题目大意
给定一个长为\(n\)的序列\(a\),要求选一个前缀与一个不相交的后缀,求这些元素异或结果的最大值。
Solution
最大的异或值,首先就要想到\(Trie\)。
把所有前缀加入\(Trie\),然后枚举后缀,一边在\(Trie\)中查询最大异或值,一边删掉一个前缀,避免会产生相交的前后缀。
注意要spj掉前缀为空与后缀为空的特殊情况,时间复杂度\(O(nlogn)\)。
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e5+10;
int ch[N*61][2],cnt[N*31];
int idx=0;
void update(ll x,int k){
int p=0;
for(int i=60;~i;i--){
int j=(x>>i)&1;
if(!ch[p][j]) ch[p][j]=++idx;
p=ch[p][j];
cnt[p]+=k;
}
}
ll query(ll x){
int p=0;
ll res=0;
for(int i=60;~i;i--){
int j=(x>>i)&1;
if(cnt[ch[p][!j]]){
res|=(1LL<<i);
p=ch[p][!j];
}else{
p=ch[p][j];
}
}
return res;
}
void solve(){
int n;
cin>>n;
ll pre=0,suf=0;
vector<ll> a(n+1);
update(0,1);
for(int i=1;i<=n;i++){
cin>>a[i];
pre^=a[i];
update(pre,1);
}
ll ans=query(0);
for(int i=n;~i;i--){
suf^=a[i];
update(pre,-1);
pre^=a[i];
ans=max(ans,query(suf));
}
cout<<ans<<'\n';
}
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T=1;
//cin>>T;
while(T--){
solve();
}
return 0;
}