• hdu 4825 Xor Sum trie树


    Xor Sum

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)


    Problem Description
    Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
     
    Input
    输入包含若干组测试数据,每组测试数据包含若干行。
    输入的第一行是一个整数T(T < 10),表示共有T组数据。
    每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。
     
    Output
    对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
    对于每个询问,输出一个正整数K,使得K与S异或值最大。
     
    Sample Input
    2 3 2 3 4 5 1 5 4 1 4 6 5 6 3
     
    Sample Output
    Case #1: 4 3 Case #2: 4
     
    Source
    思路:将每个数改成二进制,利用字典树存,找相反的异或值;
    #include<bits/stdc++.h>
    using namespace std;
    #define ll __int64
    #define mod 1000000007
    #define pi (4*atan(1.0))
    const int N=1e5+10,M=2e6+10,inf=1e9+10;
    int a[M][3],sum[M],len;
    void init()
    {
        memset(a,0,sizeof(a));
        memset(sum,0,sizeof(sum));
        len=1;
    }
    void insertt(int x)
    {
        int num[35];
        memset(num,0,sizeof(num));
        int flag=0;
        while(x)
        {
            num[flag++]=x%2;
            x/=2;
        }
        int u=0,n=34;
        for(int i=n; i>=0; i--)
        {
            if(!a[u][num[i]])
            {
                a[u][num[i]]=len++;
            }
            u=a[u][num[i]];
        }
    }
    int getans(int x)
    {
        int num[35];
        memset(num,0,sizeof(num));
        int flag=0;
        while(x)
        {
            num[flag++]=x%2;
            x/=2;
        }
        for(int i=0; i<=34; i++)
            num[i]=num[i]?0:1;
        int u=0,n=34,v,w;
        int ans=0;
        for(int i=n; i>=0; i--)
        {
            if(num[i])
            {
                v=1;
                w=0;
            }
            else
            {
                w=1;
                v=0;
            }
            if(a[u][v])
            {
                u=a[u][v];
                if(v)
                    ans+=(1<<i);
            }
            else
            {
                u=a[u][w];
                if(!v)
                    ans+=(1<<i);
            }
        }
        return ans;
    }
    int main()
    {
        int x,y,z,i,t;
        int T,cas;
        while(~scanf("%d",&T))
        {
            for(cas=1; cas<=T; cas++)
            {
                init();
                scanf("%d%d",&x,&y);
                for(i=0; i<x; i++)
                {
                    scanf("%d",&z);
                    insertt(z);
                }
                printf("Case #%d:
    ",cas);
                for(i=0; i<y; i++)
                {
                    scanf("%d",&z);
                    printf("%d
    ",getans(z));
                }
            }
        }
        return 0;
    }
    代码
  • 相关阅读:
    Typora的使用-规整笔记 让我以后的笔记内容更加整齐
    2019.11.8
    Java笔记1: 输入输出与变量常量
    2019.11.5 规整博客;整理分类;分章节发表博客
    2019.11.4 准备房子/研究汉诺塔问题和递归改变自我思维
    2013年小结
    legoblock秀上限
    阶段总结合计划
    《人月神话》读后感
    《JavaScript语言精髓与编程实践》读书笔记二
  • 原文地址:https://www.cnblogs.com/jhz033/p/5597954.html
Copyright © 2020-2023  润新知