一般异或问题都可以转换成字典树的问题,,我一开始的想法有点小问题,改一下就好了

下面的代码是逆向建树的,数据量大就不行

/*3
01字典树
根据异或性质,a1!=a2 ==> a1^x1^..^xn != a2^x1^..an
把修改转换成不同的询问
先把初始集合里没有的数建立成字典树
每次询问找的是字典树里异或x最小的值
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
int buf[maxn];
void getbuf(int a){
for(int i=;i<=;i++)
buf[i]=a%,a/=;
for(int i=,j=; i<=j; i++,j--)
swap(buf[i],buf[j]);
} struct Trie{
int root,L;
int nxt[maxn*][],end[maxn*];
int newnode(){
nxt[L][]=nxt[L][]=-;
return L++;
}
void init(){
L=;root=newnode();
}
void insert(int a){
getbuf(a);
//for(int i=1;i<=20;i++)printf("%d ",buf[i]);
int now=root;
for(int i=;i<=;i++){
if(nxt[now][buf[i]]==-)
nxt[now][buf[i]]=newnode();
now=nxt[now][buf[i]];
}
end[now]=a;
}
int query(int a){//要找和a异或最小的数,就是碰到1时就往1走,碰到0时就往0走
getbuf(a);
//for(int i=1;i<=20;i++)printf("%d ",buf[i]);
int now=root;
for(int i=;i<=;i++){
if(nxt[now][buf[i]]==-)
now=nxt[now][buf[i]^];
else now=nxt[now][buf[i]];
}
return end[now];
}
}tr;
int n,m,flag[maxn],a,Max,x;
vector<int>v;
int main(){
tr.init();
cin>>n>>m;
for(int i=;i<=n;i++){
cin>>a;flag[a]=,Max=max(a,Max);
}
for(int i=;i<=;i++)
if(flag[i]==)v.push_back(i);
for(int i=;i<v.size();i++)
tr.insert(v[i]); m--,cin>>x;
printf("%d\n",tr.query(x)^x);
while(m--){
cin>>a;
x^=a;
printf("%d\n",tr.query(x)^x);
}
}

如果是把集合中存在的元素进行建树,就不会出现字典树大小无法确定的问题,但是每次查询要改一下,即如果第i位是1,那就往字典树的0子树找,反之往1子树找,并且如果先找的子树已经满了,即mex的结果不可能再这棵子树中找到,那么就往另一颗子树找即可

#include <stdio.h>
#include <string.h>
#include<iostream>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define NODE 3200010
#define N 300010
using namespace std;
int n;
int v[N];
int node;
int next[NODE][];
int end[NODE];
int num[NODE][];
bool vis[NODE];
void add(int cur,int k)
{
memset(next[node],,sizeof(next[node]));
end[node]=;
next[cur][k]=node++;
}
int cal(int x)
{
int i,k,cur=,t1;
int res=;
for(i=;i>=;i--)
{
k=((<<i)&x)?:;
if(num[cur][k]>=<<(i)){
res+=<<i;
cur=next[cur][-k];
}else{
cur=next[cur][k];
}
if(cur==)break; //这里是为了当进入到一个个数为0的分支,可以直接break
}
//return (x^end[cur]); 如果是求最大值
return res;
}
int main()
{
int i,j,k,x,cur;
int ans,m;
//freopen("in.txt","r",stdin);
while(~scanf("%d %d",&n,&m))
{
node=;
memset(next[],,sizeof(next[]));
for(i=;i<n;i++)
{
scanf("%d",&x);
if(vis[x])continue;
vis[x]=;
v[i]=x;
cur=;
for(j=;j>=;j--)
{
k=((<<j)&x)?:;
if(next[cur][k]==)add(cur,k);
num[cur][k]++;
cur=next[cur][k];
}
end[cur]=x;
}
int t1,t2;
t1=;
for(ans=i=;i<m;i++){ //求最大值是max(ans,cal(v[i]))
cin >> t2;
t1^=t2;
cout << cal(t1) << endl;
}
}
return ;
}

另外这题用线段树解也可以,即建600000个结点,每个叶子结点维护的就是元素中的集合,然后每次查询还是按01字典树找最小异或值那一套方法就行了

cf842D 01字典树|线段树 模板见hdu4825的更多相关文章

  1. 浅谈树套树(线段树套平衡树)&学习笔记

    0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...

  2. 线段树--线段树【模板1】P3372

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含 ...

  3. Hihocoder #1077 : RMQ问题再临-线段树(线段树:结构体建树+更新叶子往上+查询+巧妙使用father[]+线段树数组要开大4倍 *【模板】)

    #1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并 ...

  4. HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)

    题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...

  5. 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新

    目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...

  6. [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)

    解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...

  7. 「BZOJ3065」带插入区间第K小值 替罪羊树×线段树

    题目描述 从前有\(n\)只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力\(a_i\).跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间\(k\)小值.他 ...

  8. 「BZOJ3600」没有人的算术 替罪羊树+线段树

    题目描述 过长--不想发图也不想发文字,所以就发链接吧-- 没有人的算术 题解 \(orz\)神题一枚 我们考虑如果插入的数不是数对,而是普通的数,这就是一道傻题了--直接线段树一顿乱上就可以了. 于 ...

  9. 权值线段树&线段树合并

    权值线段树 所谓权值线段树,就是一种维护值而非下标的线段树,我个人倾向于称呼它为值域线段树. 举个栗子:对于一个给定的数组,普通线段树可以维护某个子数组中数的和,而权值线段树可以维护某个区间内数组元素 ...

随机推荐

  1. 如何设置vmware 让别人连接你的虚拟机

    参考链接: http://blog.csdn.net/yuan1590/article/details/53504042 http://blog.csdn.net/u012110719/article ...

  2. 【报错】java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[

    报错 java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleExce ...

  3. 20165221学习基础和C语言基础调查

    1.你有什么技能比大多人(超过90%以上)更好? - 我觉得自己应该改算资质平平的那种人,如果说有什么技能比大多数人更好,我觉得应该是看过自己喜欢的书后,那种记忆能力.就比如自己从小对历史很感兴趣,小 ...

  4. 3. Python 字典 常用办法总结

    Python字典客储存任意类型的对象,如字符串.数字.元祖.列表.字典.bool等. 优点:取值方便,速度快 1.创建字典 字典由键(key)和对应值(value)成对组成. 字典也被称作关联数组或哈 ...

  5. 【转】python之模块array

    [转]python之模块array >>> import array#定义了一种序列数据结构 >>> help(array) #创建数组,相当于初始化一个数组,如: ...

  6. thinkphp提示不支持mysqli或者mysql

    确认php是否安装了php-mysql组件,nginx或apache的php服务进程

  7. 在operator =中要处理“自我赋值”

    防止自我赋值很有必要 Widget w; w = w; a[i] = a[j]; //a[i]和a[j]实际上指向同一个元素 *pi = *pj; //pi和pj实际上指向同一个元素 自我赋值的危害: ...

  8. ubuntu 16.04 修正网卡与ifname对应关系

    一台工控机,含有6个网口,但是名称  enp3s0 等等与网口顺序对应不起来. 现在修改脚本 /etc/udev/rules.d/70-persistent-net.rules ,如果文件不存在,可以 ...

  9. $Django importlib与dir知识,手写配置文件, 配置查找顺序 drf分页器&drf版本控制

    1  importlib与dir知识 # importlib简介动态导入字符串模块 # 常规导入 from ss.aa import b from ss import a print(b,type(b ...

  10. [javascript]XMLHttpRequest GET/SET HTTP头与改变HTTP METHOD示例代码

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...