Codeforces

来源:互联网 发布:java web直播源码 编辑:程序博客网 时间:2024/05/21 10:11

Codeforces - 842D - Vitya and Strange Lesson

题意可以很轻松的转化为:每个询问给定一个整数 q, 求满足 qk 在数组中存在的最小的 k
可以先将数组中的所有元素放入01Trie 中,每次询问,对于 q 的某一位 b 来说,Trieb 方向是左子树,如果左子树不满,访问左子树,否则访问右子树。最后得到的就是最小的 k

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=3e5+7;int a[N];struct Trie{    int next[N*20][2],sz[N*20],L,root,M=18;    int newnode()    {        next[L][1]=next[L][0]=-1;        sz[L]=0;        return L++;    }    void init()    {        L=0;        root=newnode();    }    int query(int x)    {        int now=root,res=0;        for(int i=M;i>=0;--i)        {            int b=((x>>i)&1);            if(next[now][b]==-1) return res;            if(sz[next[now][b]]<(1<<i)) now=next[now][b];            else            {                res|=(1<<i);                if(next[now][b^1]==-1) return res;                now=next[now][b^1];            }        }        return res;    }    void insert(int x)    {        int now=root;        ++sz[now];        for(int i=M;i>=0;--i)        {            int b=(x>>i)&1;            if(next[now][b]==-1) next[now][b]=newnode();            now=next[now][b];            ++sz[now];        }        if(sz[now]>1)        {            now=root;            --sz[now];            for(int i=M;i>=0;--i)            {                int b=(x>>i)&1;                now=next[now][b];                --sz[now];            }        }    }};Trie t;int main(){    int n,m;    scanf("%d%d",&n,&m);    t.init();    for(int i=1;i<=n;++i)    {        int k;        scanf("%d",&k);        t.insert(k);    }    int now=0;    for(int i=1;i<=m;++i)    {        int k;        scanf("%d",&k);        now^=k;        printf("%d\n",t.query(now));    }    return 0;}
原创粉丝点击