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 <map>
  3 #include <deque>
  4 #include <ctime>
  5 #include <stack>
  6 #include <cmath>
  7 #include <queue>
  8 #include <string>
  9 #include <cstdio>
 10 #include <vector>
 11 #include <iomanip>
 12 #include <cstring>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16
 17 typedef long long LL;
 18 typedef pair<LL, LL> pll;
 19 typedef pair<LL, int> pli;
 20 typedef pair<int, int> pii;
 21 typedef unsigned long long uLL;
 22
 23 #define lson rt<<1
 24 #define rson rt<<1|1
 25 #define name2str(name)(#name)
 26 #define bug printf("**********\n");
 27 #define IO ios::sync_with_stdio(false);
 28 #define debug(x) cout<<#x<<"=["<<x<<"]"<<endl;
 29 #define FIN freopen("/home/dillonh/CLionProjects/in.txt","r",stdin);
 30
 31 const double eps = 1e-8;
 32 const int maxn = 1e5 + 7;
 33 const int inf = 0x3f3f3f3f;
 34 const double pi = acos(-1.0);
 35 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
 36
 37 int t, n, q, le, root;
 38 LL x;
 39 int a[35];
 40
 41 struct node{
 42     int cnt;
 43     int nxt[3];
 44
 45     void init(){
 46         cnt = 0;
 47         nxt[0] = nxt[1] = -1;
 48     }
 49 }T[maxn*55];
 50
 51 void insert(LL n){
 52     int now = root;
 53     for(int i = 0; i <= 32; i++) {
 54         a[i] = n % 2;
 55         n /= 2;
 56     }
 57     for(int i = 32; i >= 0; i--){
 58         int x = a[i];
 59         if(T[now].nxt[x] == -1){
 60             T[le].init();
 61             T[now].nxt[x] = le++;
 62         }
 63         now = T[now].nxt[x];
 64         T[now].cnt++;
 65     }
 66 }
 67
 68 LL search(LL n){
 69     int now = root;
 70     LL ans = 0;
 71     for(int i = 0; i <= 32; i++) {
 72         a[i] = n % 2;
 73         n /= 2;
 74     }
 75     for(int i = 32; i >= 0; i--){
 76         int x = a[i];
 77         if(T[now].nxt[1 - x] != -1) {
 78             if(x == 0) ans += 1LL << i;
 79             now = T[now].nxt[1-x];
 80         } else {
 81             if(x == 1) ans += 1LL << i;
 82             now = T[now].nxt[x];
 83         }
 84     }
 85     return ans;
 86 }
 87
 88 int main() {
 89     int icase = 0;
 90     scanf("%d", &t);
 91     while(t--) {
 92         le = 1;
 93         T[0].init();
 94         scanf("%d%d", &n, &q);
 95         for(int i = 1; i <= n; i++) {
 96             scanf("%lld", &x);
 97             insert(x);
 98         }
 99         printf("Case #%d:\n", ++icase);
100         for(int i = 1; i <= q; i++) {
101             scanf("%lld", &x);
102             printf("%lld\n", search(x));
103         }
104     }
105     return 0;
106 }

原文地址:https://www.cnblogs.com/Dillonh/p/9752029.html

时间: 2024-11-09 02:58:45

Xor Sum(HDU4825 + 字典树)的相关文章

Xor Sum 01字典树 hdu4825

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

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; } }; n

HDU5715 XOR 游戏 二分+字典树+dp

当时Astar复赛的时候只做出1题,赛后补题(很长时间后才补,懒真是要命),发现这是第二简单的 分析: 这个题,可以每次二分区间的最小异或和 进行check的时候用dp进行判断,dp[i][j]代表前i个元素分成j个区间,j是最后一个区间的最后一个元素 如果dp[i][j]为真,表明每个区间长度大于L,异或和大于mid 否则为假 返回dp[n][m]就好 复杂度度 O(30^2*nm) 吐槽:和异或相关的题总是和字典树贪心有关,又是一道,铭记铭记 #include <stdio.h> #inc

HDU4825 Xor Sum(贪心+Trie树)

今天本来想写一个可持久化Trie树,发现这道题一直没做就补上了. 其实思路很简单,假如说两个数,和同一个数异或,很显然,由于进制,高位上的一个1可以大于低位上所有1,所以即使后面的情况再糟糕,也比取后面好的值高(其实就是1000比0111大) 所以可以建一个01线段树,从高往低插入一个数,比较时取反即可^_^ 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace st

NBUT 1525 Cow Xor(01字典树+前缀思想)

[1525] Cow Xor 时间限制: 2000 ms 内存限制: 65535 K 问题描述 农民约翰在喂奶牛的时候被另一个问题卡住了.他的所有N(1 <= N <= 100,000)个奶牛在他面前排成一行(按序号1..N的顺序),按照它们的社会等级排序.奶牛#1有最高的社会等级,奶牛#N最低.每个奶牛同时被指定了一个不唯一的附加值,这个数在0..2^21 - 1的范围内. 帮助农民约翰找出应该从哪一头奶牛开始喂,使得从这头奶牛开始的一个连续的子序列上,奶牛的附加值的异或最大. 如果有多个这

POJ 3764 - The xor-longest Path - [DFS+字典树变形]

题目链接:http://poj.org/problem?id=3764 Time Limit: 2000MS Memory Limit: 65536K Description In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p: $_{xor}length(p) = \bigoplus_{e \in p}w(e)$ $\oplus$

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