01字典树

来源:互联网 发布:mac 文件重命名 命令 编辑:程序博客网 时间:2024/05/05 22:22

奇迹的魔法啊,再度出现!

想对你说的话,如山似海。——AsahinaMiraiAsahinaMirai

决战之后,魔法界和无魔法界分离,为了和RicoRico再次相见,MiraiMirai必须用经受考验,唤醒奇迹的魔法。
那考验就是——出现了nn个非负整数a1,a2,…,ana1,a2,…,an,
对于mm次询问,第jj次询问给定一个正整数xjxj,
输出max{a1XORxj,a2XORxj,…,anXORxj}max{a1XORxj,a2XORxj,…,anXORxj}。

XORXOR运算:0XOR1=10XOR1=1,1XOR0=11XOR0=1,0XOR0=00XOR0=0,1XOR1=01XOR1=0。
按位XORXOR运算:对两个数的二进制位依次进行XORXOR运算。
还对XORXOR运算不懂的请去百度或谷歌一下:异或。

Input

输入的第一行为一个正整数nn,
接下来一行是nn个非负整数a1,a2,…,ana1,a2,…,an。
接下来为一个正整数mm,
接下来一行,为mm个非负整数x1,x2,…,xmx1,x2,…,xm。

Output

输出mm行,每行11个值,表示所求答案。

Sample Input
51 8 0 5 1457 14 10 4 2
Sample Output
1515151212
Hint
1≤n≤1000001≤n≤100000, 1≤m≤1000001≤m≤100000, 0≤ai≤21474836470≤ai≤2147483647, 0≤xi≤2147483647

用数组模拟

#include<cstdio>#include<cstring>using namespace std;const int maxn = 1e5 + 5;int tree[32 * maxn][2];int n, m ,root,rt;int newnode(){    rt++;    tree[rt][0] = tree[rt][1] = -1;    return rt;}void init(){    rt = 0;    root = newnode();}void insert(int x){    int now = root;    for (int i = 31; i >= 0; i--) {        int go = (x >> i) & 1;        if (tree[now][go] == -1) {            int next = newnode();            tree[now][go] = next;            now = next;        }        else now = tree[now][go];    }}int query(int x){    int ans = 0,now=root;    for (int i = 31; i >= 0; i--) {        int go = (x >> i) & 1;        if (tree[now][!go] != -1) {            ans |= 1 << i;            now = tree[now][!go];        }        else now = tree[now][go];    }    return ans;}int main(){    while (scanf("%d", &n) != EOF) {        init();        for (int i = 1; i <= n; i++) {            int x;            scanf("%d",&x);            insert(x);        }        scanf("%d",&m);        for (int i = 1; i <= m; i++) {            int x;            scanf("%d",&x);            printf("%d\n",query(x));        }    }    return 0;}

使用指针存树

#include<cstdio>#include<algorithm>using namespace std;struct node {    node *lc, *rc;    node() {        lc = rc = NULL;    }};int n, m;void insert(int x, node *h){    node *s = h;    for (int i = 31; i >= 0; i--) {        int a = (x >> i) & 1;        if (a == 1 && s->rc == NULL) {            node *t = new node;            s->rc = t;            s = t;        }        else if(a==1&&s->rc!=NULL){            s=s->rc;        }        else if (a == 0 && s->lc == NULL) {            node *t = new node;            s->lc = t;            s = t;        }        else if(a==0&&s->lc!=NULL)            s=s->lc;    }}int find(int x, node *h){    int ans=0;    node *s=h;    for(int i=31;i>=0;i--){        int a=(x>>i)&1;        if(a==0){            if(s->rc!=NULL){                ans|=1<<i;                s=s->rc;            }            else if(s->lc!=NULL)                s=s->lc;        }        else{            if(s->lc!=NULL){                ans|=1<<i;                s=s->lc;            }            else if(s->rc!=NULL)                s=s->rc;        }    }    return ans;}int main(){    while (scanf("%d", &n) != EOF) {        node *head = new node;        //head->rc=head->lc=NULL;        for (int i = 1; i <= n; i++) {            int x;            scanf("%d", &x);            insert(x, head);        }        scanf("%d",&m);        for (int i = 1; i <= m; i++) {            int x;            scanf("%d",&x);            printf("%d\n",find(x,head));        }    }    return 0;}

用数组模拟跑了132ms,内存12m多一点,然而用指针跑了220ms,内存跑了23m多,不知道多跑的内存在哪

原创粉丝点击