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;
}
posted @   fengxue-K  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示