Vitya and Strange Lesson (01字典树)

Vitya and Strange Lesson

https://ac.nowcoder.com/acm/problem/112209

题意:给定一组数,然后对所有的数进行异或操作m次异或操作,问你每次操作后,没有出现过的最小的非负整数

题解:
首先需要一个性质(a^b)^c=a^(b^c);
所以我们没有必要对于所有的数进行异或操作。
我们只需要设一个ans=0,每次用输入进来的数于ans进行异或即可。

其次,我们把没有出现过的数字加入进字典树,这样的话我们从高位到低位寻找与当前ans按位 比较相同的数字,如果不相同那么我们就给 返回值加上当前位的值。最后返回值极为最小mex。

/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>

//#define int long long
#define endl '\n'
#define Accepted 0
#define AK main()
#define I_can signed
using namespace std;
const int maxn =1e7+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
using namespace std;

int trie[maxn][2];
bool visited[maxn];
int cnt;

void ins(int x){
    int node=0;
    for(int i=21;i>=0;i--){
        int t=(x>>i)&1;
        if(!trie[node][t]) trie[node][t]=++cnt;
        node=trie[node][t];
    }
    return ;
}


int ifind(int x){
    int res=0,node=0;
    for(int i=21;i>=0;i--){
        int t=(x>>i)&1;
        if(trie[node][t]) node=trie[node][t];
        else{
            res|=1<<i;
            node=trie[node][t^1];
        }
    }
    return res;
}

signed main()
{
    //ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    memset(visited,false,sizeof visited);
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        visited[x]=true;
    }
    int ans=0;
    for(int i=0;i<600010;i++){
        if(!visited[i]){
            ins(i);
        }
    }
    for(int i=0;i<m;i++){
        int x;
        cin>>x;
        ans^=x;
        cout<<ifind(ans)<<endl;
    }
    return 0;
}

全部评论

相关推荐

Pandaileee:校友加油我现在也只有一个保底太难了
点赞 评论 收藏
分享
努力学习的小绵羊:我反倒觉得这种挺好的,给不到我想要的就别浪费大家时间了
点赞 评论 收藏
分享
11-13 20:32
门头沟学院 Java
面向未来编程code:我没看到他咋急,他不就问你个问题。。。
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务