题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1295

题目来源: HackerRank
基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题
 收藏
 关注
给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R)。求A[L] 至 A[R] 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少?
Input
第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= Q <= 50000)。
第2 - N+1行:每行1个数,对应数组A的元素(0 <= A[i] <= 10^9)。
第N+2 - N+Q+1行:每行3个数X, L, R,中间用空格分隔。(0 <= X <= 10^9,0 <= L <= R < N)
Output
输出共Q行,对应数组A的区间[L,R]中的数与X进行异或运算,所能得到的最大值。
Input示例
15 8  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
10 5 9
1023 6 6
33 4 7
182 4 9
181 0 12
5 9 14
99 7 8
33 9 13
Output示例
13  
1016  
41  
191  
191  
15  
107  
47

题解:

1.此题(HDU4825 Xor Sum)的加强版

2.由于要求的是x与区间[l,r]的某个数异或值最大,所以在Trie树的基础上,可以模仿可持久化线段树,建立一棵可持久化Trie树。这样就可以得到每插入一个数时的历史版本的Trie树。

代码如下

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e5+; struct Trie
{
int end[*MAXN], next[*MAXN][];
int root[MAXN], L = ;
int newnode()
{
next[L][] = next[L][] = -;
end[L++] = ;
return L-;
}
void init()
{
L = ;
}
void build(LL val) //初始化版本
{
int tmp = root[];
for(int i = ; i>=; i--)
{
int way = (val>>i)&;
if(next[tmp][way]==-) next[tmp][way] = newnode();
tmp = next[tmp][way];
}
}
int insert(int preroot, LL val)
{
int newroot = newnode(), rootbuf = newroot;
for(int i = ; i>=; i--)
{
int way = (val>>i)&;
next[newroot][way] = newnode(); //要走的路,新开出来
next[newroot][!way] = next[preroot][!way]; //另一条路,指向上一个历史版本的 newroot = next[newroot][way];
preroot = next[preroot][way];
end[newroot] = end[preroot]+; //叠加
}
return rootbuf;
}
LL query(int Lroot, int Rroot, LL val)
{
LL ret = ;
for(int i = ; i>=; i--)
{
ret <<= ;
int way = (val>>i)&;
if(next[Lroot][!way]!=- && (end[next[Rroot][!way]]-end[next[Lroot][!way]]>))
{
ret ^= ;
Lroot = next[Lroot][!way];
Rroot = next[Rroot][!way];
}
else
{
Lroot = next[Lroot][way];
Rroot = next[Rroot][way];
}
}
return ret;
}
};
Trie T; LL a[MAXN];
int main()
{
int n, q;
while(scanf("%d%d",&n,&q)!=EOF)
{
T.init();
T.root[] = T.newnode();
for(int i = ; i<=n; i++) //建立初始化版本
{
scanf("%lld",&a[i]);
T.build(a[i]);
}
for(int i = ; i<=n; i++) //每插入一个数,就生成一个历史版本的Trie树
T.root[i] = T.insert(T.root[i-],a[i]); while(q--)
{
int x, l, r;
scanf("%d%d%d",&x,&l,&r);
l++; r++;
printf("%lld\n", T.query(T.root[l-],T.root[r],1LL*x));
}
}
}

51Nod XOR key —— 区间最大异或值 可持久化字典树的更多相关文章

  1. bzoj 3261 最大异或和 可持久化字典树(01树)

    题目传送门 思路: 由异或的性质可得,题目要求的式子可以转化成求$max(pre[n]^x^pre[i])$,$pre[i]$表示前缀异或和,那么我们现在就要求出这个东西,所以用可持久化字典树来求,每 ...

  2. AcWing 144. 最长异或值路径 01字典树打卡

    给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n, ...

  3. 51nod 1295 XOR key-区间异或最大值-可持久化01Trie树(模板)

    1295 XOR key 2 秒 262,144 KB 160 分 6 级题   给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求A[L] ...

  4. SPOJ MAXOR (分块 || 可持久化字典树 || 异或)(好题)

    You are given a sequence A[1], A[2], ..., A[N]. (0 ≤ A[i] < 231, 1 ≤ N ≤ 12000). A query is defin ...

  5. 【BZOJ 3261】最大异或和【可持久化字典树】

    题意 给出一个长度为n的整数序列,给出m个操作.操作有两种.1,Ax表示在序列结尾增加x.2,Qlrx表示找到一个位置p满足 l<=p<=r,使得a[p] xor a[p+1]xor... ...

  6. Codeforces 979 D. Kuro and GCD and XOR and SUM(异或和,01字典树)

    Codeforces 979 D. Kuro and GCD and XOR and SUM 题目大意:有两种操作:①给一个数v,加入数组a中②给出三个数x,k,s:从当前数组a中找出一个数u满足 u ...

  7. 【bzoj3689】异或之 可持久化Trie树+堆

    题目描述 给定n个非负整数A[1], A[2], ……, A[n].对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n ...

  8. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

  9. BZOJ3261: 最大异或和(可持久化trie树)

    题意 题目链接 Sol 设\(sum[i]\)表示\(1 - i\)的异或和 首先把每个询问的\(x \oplus sum[n]\)就变成了询问前缀最大值 可持久化Trie树维护前缀xor,建树的时候 ...

随机推荐

  1. 查看网络port占用

    Linux和Mac下通用: 1.  利用 netstat 查看网络状态命令: netstat -an|grep port号 2. 利用list open file 命令打开文件(一切都是文件. 包含网 ...

  2. 数据结构之---C语言实现图的数组(邻接矩阵)存储表示

    //图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #define MAX_VEX_NUM 50 typedef c ...

  3. kill -signal

    1. SIGHUP 启动被终止的进程,可让该PID重新读取配置文件,类似于重启服务 对应的数字为1 9.SIGTERM 以正常的结束进程来终止进程 15.SIGSTOP 暂停一个进程相当于crtl+z

  4. 【Excle数据透视】如何创建一个数据透视表

    数据透视表可以汇总.分析.浏览和提供工作表数据或外部数据源的汇总数据 创建方法一 通过”插入”创建,具体操作请看下图: 创建方法二 通过快捷键创建 使用[ALT+D+P]创建 首先按下alt键,然后依 ...

  5. PM2.5

    http://baike.baidu.com/view/1423678.htm PM2.5是指大气中直径小于或等于2.5微米的颗粒物,也称为可入肺颗粒物.虽然PM2.5只是地球大气成分中含量很少的组分 ...

  6. Atitit.ati&#160;dwr的原理and设计&#160;attilax&#160;总结&#160;java&#160;php&#160;版本号

    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本号 1. dwr的长处相对于ajax来说.. 1 2. DWR工作原理 1 3. Dwr的架构 2 4. 自己 ...

  7. 一起学android之怎样设置TextView中不同字段的字体颜色(22)

    在这里先看看效果图: OK,有时候,在我们的项目中会要求TextView中文本有一部分的字体颜色不一样.这时我们应该使用 SpannableStringBuilder这个工具类,当然这个类的功能非常强 ...

  8. anaconda3.5 3.6 2.7

    https://repo.continuum.io/archive/ Filename Size Last Modified MD5 Anaconda2-5.0.1-Linux-x86.sh 413. ...

  9. jQuery Validate(三)

    这里,我们再说说radio.checkbox.select的验证方式. 1.用新版的写法进行验证. <!DOCTYPE html> <html> <head> &l ...

  10. String 的fomat方法日期转换

    一.常规类型.字符类型和数值类型的格式说明符的语法如下:%[argument_index$][flags][width][.precision]conversion 可选的 argument_inde ...