CF842D Vitya and Strange Lesson(01Trie)

比较考验思维,考虑使用01trie先将数字建立trie,每次存在一下异或的结果。

对于异或出来的值,在01trie上贪心的找,如果能找到和他当前位相等的值时,判断一下他的子树中的数字是否满足前面所有的数都在

如果都在,说明答案要大,如果不在,说明就在当前子树

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=1e6+10;
const int M=2e6+10;
const int inf=0x3f3f3f3f;
int tr[N][26],idx,rt;
int cnt[N],sw;
int vis[N];
void insert(int x){
    int p=rt;
    int i;
    for(i=20;i>=0;i--){
        int sign=(x>>i)&1;
        if(!tr[p][sign]){
            tr[p][sign]=++idx;
        }
        p=tr[p][sign];
        cnt[p]++;
    }
}
int query(int x){
    int p=rt;
    ll ans=0;
    for(int i=20,p=0;i>=0;--i){
        int type=x>>i&1;
        if(cnt[tr[p][type]]==(1<<i)) ans|=(1<<i),p=tr[p][type^1];
        else p=tr[p][type];
    }
    return ans;
}
int main(){
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    int i;
    for(i=1;i<=n;i++){
        int x;
        cin>>x;
        if(vis[x])
            continue;
        vis[x]=1;
        insert(x);
    }
    sw=0;
    while(m--){
        int x;
        cin>>x;
        sw^=x;
        cout<<query(sw)<<endl;
    }
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/13635908.html