hdu4825 字典树 XOR

用字典树思想来做。对于一个数,给出他的二进制,然后更具二进制建立字典树,然后每次询问的时候的数也给出二进制,如果当前为1,那就向0走,为0,向1走。

#include<stdio.h>
#include<string.h>
const int maxn = 100010;
struct node
{
    int flag;
    int num;
    node *next[2];
    void init()
    {
        next[0]=next[1]=NULL;
        num=0;
        flag=-1;
    }
};
node *trie,*p=NULL;
int a[maxn],n,m;
void init()
{
    trie=new node;
    trie->init();
}
void add(int x)
{
    int i,j;
    for(i=30; i>=0; i--)
    {
        int t;
        if(x&(1<<i))t=1;
        else t=0;
        if(t)
        {
            if(p->next[t]==NULL)
            {
                node *q=new node;
                q->init();
                p->next[t]=q;
            }
            p=p->next[t];
            p->num++;
        }
        else
        {
            if(p->next[t]==NULL)
            {
                node *q=new node;
                q->init();
                p->next[t]=q;
            }
            p=p->next[t];
            p->num++;
        }
    }
    p->flag=x;
}
int query(int x)
{
    int ret=0;
    int i,j;
    for(i=30; i>=0; i--)
    {
        int t;
        if(x&(1<<i))
            t=1;
        else t=0;
        if(t)
        {
            if(p->next[0]!=NULL)
                p=p->next[0];
            else p=p->next[1];
        }
        else
        {
            if(p->next[1]!=NULL)
                p=p->next[1];
            else p=p->next[0];
        }
    }
    return p->flag;
}
void Del(node *trie)
{
    for(int i=0;i<=1;i++)
    {
        if(trie->next[i]!=NULL)
            Del(trie->next[i]);
    }
    delete trie;
}
int main()
{
    int i,t,j,ff=0;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d%d",&n,&m);
        for(i=0; i<n; i++)
        {
            p=trie;
            scanf("%d",&a[i]);
            add(a[i]);
        }
        printf("Case #%d:\n",++ff);
        while(m--)
        {
            int x;
            p=trie;
            scanf("%d",&x);
            printf("%d\n",query(x));
        }
        Del(trie);
    }
}
时间: 2024-08-26 18:26:08

hdu4825 字典树 XOR的相关文章

Xor Sum(HDU4825 + 字典树)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4825 题目: 题意: 先给你n个数,再进行q次查询,每次查询数s与原来给的n个数异或和最大的数. 思路: 建一棵字典树,将n个数转换成二进制存进去,每次查询时,对s的每一位进行匹配(从高位开始匹配,毕竟你低位再大也没有一位高位大效果好,如34 <42),匹配第i位时为了值尽可能大应先匹配1-a[i]再匹配a[i]. 代码实现如下: 1 #include <set> 2 #include &

HDU--4825 Xor Sum (字典树)

题目链接:HDU--4825 Xor Sum mmp sb字典树因为数组开的不够大一直wa 不是报的 re!!! 找了一下午bug 草 把每个数转化成二进制存字典树里面 然后尽量取与x这个位置上不相同的 先来一个最原始的代码写的跟屎一样的 #include<iostream> #include<cstring> #include<algorithm> #include<string.h> #include<stdio.h> #include<

【Hdu4825】Xor Sum(01字典树)

Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助.你能证明人类的智慧么? Solution 01字典树入门题 Code #include

HDU 4825 Xor Sum(经典01字典树+贪心)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 1555    Accepted Submission(s): 657 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

ACM学习历程—HDU 5536 Chip Factory(xor &amp;&amp; 字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题目大意是给了一个序列,求(si+sj)^sk的最大值. 首先n有1000,暴力理论上是不行的. 此外题目中说大数据只有10组,小数据最多n只有100.(那么c*n^2的复杂度应该差不多) 于是可以考虑枚举i和j,然后匹配k. 于是可以先把所有s[k]全部存进一个字典树, 然后枚举s[i]和s[j],由于i.j.k互不相等,于是先从字典树里面删掉s[i]和s[j],然后对s[i]+s[j]这个

hdu5269 ZYB loves Xor I 异或,字典树

hdu5269  ZYB loves Xor I   异或,字典树 ZYB loves Xor I Accepts: 142 Submissions: 696 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 ZYB喜欢研究Xor,现在他得到了一个长度为nn的数组A.于是他想知道:对于所有数对(i,j)(i \in [1,n],j \in [1,n])(i,j)(i∈[1,n

2014百度之星资格赛—— Xor Sum(01字典树)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起

ACM学习历程—POJ 3764 The xor-longest Path(xor &amp;&amp; 字典树 &amp;&amp; 贪心)

题目链接:http://poj.org/problem?id=3764 题目大意是在树上求一条路径,使得xor和最大. 由于是在树上,所以两个结点之间应有唯一路径. 而xor(u, v) = xor(0, u)^xor(0, v). 所以如果预处理出0结点到所有结点的xor路径和,问题就转换成了求n个数中取出两个数,使得xor最大. 这个之前用字典树处理过类似问题. 代码: #include <iostream> #include <cstdio> #include <cst

CODEVS1187 Xor最大路径 (字典树)

由于权值是在边上,所以很容易发现一个性质:d(x,y)=d(x,root) xor d(y,root). 因为有了这个性质,那么就很好做了.对于每一个点统计到root的距离,记为f 数组. 将f数组里的每个值插进按照二进制位插进字典树里面. 枚举每一个点,然后在字典树中搜索最大的xor值就可以了. Program CODEVS1187; const maxn=100008; type arr=record u,v,w,next:int64; end; type arr1=record next: