zoukankan      html  css  js  c++  java
  • 01字典树入门

    题目传送:http://acm.hdu.edu.cn/showproblem.php?pid=4825

    Xor Sum

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

    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

    AC code:

     1 #include <bits/stdc++.h>
     2 #define INF 0x3f3f3f3f
     3 #define ll long long int
     4 using namespace std;
     5 
     6 const int MAXN = 1e5+10;
     7 int ch[32*MAXN][2];
     8 ll value[32*MAXN];
     9 int node_cnt;
    10 
    11 inline void init()
    12 {
    13     node_cnt = 1;
    14     memset(ch[0], 0, sizeof(ch));
    15 }
    16 inline void Insert(ll x)
    17 {
    18     int cur = 0;
    19     for(int i = 32; i >= 0; --i){
    20         int index = (x>>i)&1;
    21         if(!ch[cur][index]){
    22             memset(ch[node_cnt], 0, sizeof(ch[node_cnt]));
    23             ch[cur][index] = node_cnt;
    24             value[node_cnt++] = 0;
    25         }
    26     cur = ch[cur][index];
    27     }
    28     value[cur] = x;
    29 }
    30 
    31 ll query(ll x)
    32 {
    33     int cur = 0;
    34     for(int i = 32; i >= 0; --i){
    35         int index = (x>>i)&1;
    36         if(ch[cur][index^1]) cur = ch[cur][index^1];
    37         else cur = ch[cur][index];
    38     }
    39     return value[cur];
    40 }
    41 
    42 int main()
    43 {
    44     int T_case, N, M;
    45     scanf("%d", &T_case);
    46     for(int ca = 1; ca <= T_case; ca++)
    47     {
    48         init();
    49         scanf("%d %d", &N, &M);
    50         for(int i = 0; i < N; i++)
    51         {
    52             ll temp;
    53             scanf("%lld", &temp);
    54             Insert(temp);
    55         }
    56         printf("Case #%d:
    ", ca);
    57         while(M--){
    58             ll tp;
    59             scanf("%lld", &tp);
    60             printf("%lld
    ", query(tp));
    61         }
    62     }
    63     return 0;
    64 }
    View Code

    01字典树入门:

    https://blog.csdn.net/miracle_ma/article/details/51484054

    https://blog.csdn.net/thesprit/article/details/52065241

    https://www.cnblogs.com/Rubbishes/p/7611187.html

    https://blog.csdn.net/solardomo/article/details/52168853

  • 相关阅读:
    Java技术路线--2循环
    Java技术路线--1基本类型与包装类
    Linux内存管理之UMA模型和NUMA模型
    最长XX子串/数组/子序列
    epoll LT 模式和 ET 模式详解
    OS篇:OS中进程的阻塞与挂起的区别
    约瑟夫环问题
    最大公约数和最小公倍数
    C++之寻找素数(素数筛)
    Linux OOM机制分析
  • 原文地址:https://www.cnblogs.com/ymzjj/p/9544240.html
Copyright © 2011-2022 走看看