zoukankan      html  css  js  c++  java
  • HDU 4825 Xor Sum (trie树处理异或)

    Xor Sum

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
    Total Submission(s): 3647    Accepted Submission(s): 1595


    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

    分析

    要求求出原集合中与所给的数异或值最大的数。

    建立一颗trie树,左边是0,右边是1。将所有数放到trie树中。

    那么,对于给定的数x,将x二进制分解,在trie中从高位往低位走,每一位最好是和x不同(异或:不同为1,相同为0)。

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 const int N = 5000100;
     7 
     8 inline char nc() {
     9     static char buf[100000],*p1=buf,*p2=buf;
    10     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    11 }
    12 inline int read() {
    13     int x = 0,f = 1;char ch = nc();
    14     for (; ch<'0'||ch>'9'; ch=nc()) if(x=='-')f=-1;
    15     for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
    16     return x * f;
    17 }
    18 struct Trie{
    19     int val[N],ch[N][2];
    20     int cnt;
    21     void init() {
    22         memset(ch,0,sizeof(ch));
    23         memset(val,0,sizeof(val));
    24         cnt = 0;
    25     }
    26     void Insert(int x) {
    27         int u = 0;
    28         for (int i=31; i>=0; --i) {
    29             int c = (x&(1<<i)) > 0;
    30             if (!ch[u][c]) ch[u][c] = ++cnt;
    31             u = ch[u][c];
    32         }
    33         val[u] = x;
    34     }
    35     int Query(int x) {
    36         int u = 0;
    37         for (int i=31; i>=0; --i) {
    38             int c = (x&(1<<i))>0;
    39             if (ch[u][!c]) u = ch[u][!c];
    40             else if(ch[u][c]) u = ch[u][c]; // 
    41         }
    42         return val[u];
    43     }
    44 }t;
    45 
    46 int main () {
    47     int T = read();
    48     for (int Case=1; Case<=T; ++Case) {
    49         t.init();
    50         int n = read(),m = read();
    51         for (int i=1; i<=n; ++i) {
    52             int a = read();
    53             t.Insert(a);
    54         }
    55         printf("Case #%d:
    ",Case);
    56         while (m--) {
    57             int a = read();
    58             printf("%d
    ",t.Query(a));
    59         }
    60     }
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    Python之路——内置函数
    Python之路——迭代器与生成器
    Python之路——函数
    Python之路——琐碎知识
    oracle 11g ocp 笔记(17)--rman高级功能
    oracle 11g ocp 笔记(16)--使用rman进行恢复
    oracle 11g ocp 笔记(15)--使用rman进行备份
    oracle 11g ocp 笔记(14)--数据库备份和恢复配置
    oracle 11g ocp 笔记(13)--子查询和集合运算符
    oracle 11g ocp 笔记(12)--sql关联
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8439138.html
Copyright © 2011-2022 走看看