HDU 4825:Xor Sum(Trie)

http://acm.hdu.edu.cn/showproblem.php?pid=4825

题意:给出N个数,M个询问,每个询问给出一个X,问在这N个数中哪个数和X异或后结果最大。

思路:可以用Trie构造出sigmaSize为0和1的点,先将N个数插入Trie,然后询问在Trie上尽量找可以不同的数,不同的话异或起来是最大的。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <string>
 6 #include <cmath>
 7 #include <queue>
 8 #include <vector>
 9 using namespace std;
10 #define N 2000010
11 int a[100005];
12 struct Trie
13 {
14     int ch[N][2], num; //注意节点数要开大,因为每个N可能有很多个节点
15     int val[N];
16     void init()
17     {
18         num = 1;
19         memset(ch[0], 0, sizeof(ch[0]));
20     }
21
22     void Update(int x, int id)
23     {
24         int u = 0;
25         for(int i = 31; i >= 0; i--) {
26             int v = ((1 << i) & x) > 0 ? 1 : 0;
27             if(!ch[u][v]) {
28                 memset(ch[num], 0, sizeof(ch[num]));
29                 val[num] = 0;
30                 ch[u][v] = num++;
31             }
32             u = ch[u][v];
33         }
34         val[u] = id;
35     }
36
37     int Query(int x)
38     {
39         int u = 0;
40         for(int i = 31; i >= 0; i--) {
41             int v = ((1 << i) & x) > 0 ? 1 : 0;
42             v = !v;
43             if(ch[u][v]) {
44                 u = ch[u][v];
45             } else{
46                 u = ch[u][!v];
47             }
48         }
49         return val[u];
50     }
51 }trie;
52
53 int main()
54 {
55     int t;
56     scanf("%d", &t);
57     for(int cas = 1; cas <= t; cas++) {
58         int n, m;
59         scanf("%d%d", &n, &m);
60         trie.init();
61         for(int i = 1; i <= n; i++) {
62             scanf("%d", &a[i]);
63             trie.Update(a[i], i);
64         }
65         printf("Case #%d:\n", cas);
66         for(int i = 1; i <= m; i++) {
67             long long q;
68             scanf("%d", &q);
69             printf("%d\n", a[trie.Query(q)]);
70         }
71     }
72     return 0;
73 }
时间: 2024-10-27 11:32:31

HDU 4825:Xor Sum(Trie)的相关文章

HDU 1003:Max Sum(DP)

Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 142742    Accepted Submission(s): 33225 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max s

HDU 6058 Kanade&#39;s sum(链表)

http://acm.hdu.edu.cn/showproblem.php?pid=6058 题意:找出所有区间第K大的值之和. 思路: 又有点贡献值的味道,就是考虑当前这个数贡献了几个区间. 然后往左和往右分别找大于当前数的k-1个数,这样就可以确定区间的个数,这要求我们从小到大找 并且找完之后需要删除这个数,用链表来维护. 删除元素的目的是为了加速,保证了当前查找的元素是最小值,所以只需要跳跃寻找k次就可以.具体看代码. 1 #include<iostream> 2 #include<

HDU 1247 Hat&#39;s words(Trie)

HDU 1247 Hat's words(Trie) ACM 题目地址: HDU 1247 Hat's words 题意: 给些单词,问每个单词是否能用另外两个单词拼出. 分析: 直接保存到trie里面,然后暴力切割查询即可. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: 1247.cpp * Create Date: 2014-09-24 11:04:11 * Descripton: */ #include <cstdio

HDU-1003:Max Sum(优化)

Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 287192    Accepted Submission(s): 68202 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max su

hdu 4825 Xor Sum (建树) 2014年百度之星程序设计大赛 - 资格赛 1003

题目 题意:给n个数,m次询问,每次给一个数,求这n个数里与这个数 异或 最大的数. 思路:建一个类似字典数的数,把每一个数用 32位的0或者1 表示,查找从高位向底位找,优先找不同的,如果没有不同的,就找相同的. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 #define LL l

HDU 4825-Xor Sum(trie)

题意: 给你一组数,开始询问给一个数  求组中与该数异或值最大的数. 分析:根据异或的特点 要想得到的异或值最大 尽可能的让两个数的每位都相反 先把给定的一组数建树,数的最后一位对应的节点保存这个数的位置(放便取) 对于每个询问 在搜树时优先考虑和当前数位相反的节点. #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include &

HDU 2767:Proving Equivalences(强连通)

http://acm.hdu.edu.cn/showproblem.php?pid=2767 题意:给出n个点m条边,问在m条边的基础上,最小再添加多少条边可以让图变成强连通.思路:强连通分量缩点后找入度为0和出度为0的点,因为在强连通图里面没有一个点的入度和出度都为0,所以取出度为0的点和入度为0的点中的最大值就是答案.(要特判强连通分量数为1的情况) 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostre

HDU 1890:Robotic Sort(Splay)

http://acm.hdu.edu.cn/showproblem.php?pid=1890 题意:有一个无序序列,经过不断地翻转,使得最后的序列是一个升序的序列,而且如果相同数字要使在原本序列靠前的在前面.对于每一个位置,输出于哪个位置翻转. 思路:想通了之后其实挺简单的,不过挺巧妙.一开始先记录每一个位的pos,并对数组升序排序,然后我们从小到大枚举数组里的元素,对于每个元素,我们可以知道:i 就是翻转后应当在序列中的位置,a[i].pos就是它在原序列的位置.这个时候,我们只要在建树的时候

HDU 5876:Sparse Graph(BFS)

http://acm.hdu.edu.cn/showproblem.php?pid=5876 Sparse Graph Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices such that two distinct vertices of H are adjacent if and only if they are not adjacent in G