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

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

/*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. 遍历系统中所有的进程,可根据名字或ID查找某一个线程

    我们这根据名字查找进程,获取其ID /*@brief 获取找到的与指定进程名相符的第一个进程ID * @param [in] cpszExeFileName 进程可执行文件名(不带路径) * @par ...

  2. VGGNet学习——实践

    0 - DataSet http://www.csc.kth.se/~att/Site/Animals.html 1 - Code 1.1 - Import Packages import tenso ...

  3. Javascript - Jquery - 筛选

    筛选(JQuery Selector) JQuery是一个JavaScript库,它极大地简化了JavaScript编程.整个JQuery库的方法都在$这个工厂函数里,我们只需要使用$函数,而$函数会 ...

  4. python,os方法的简单介绍

    ''' 这一个章节是学习os及os.path的用法 ''' #学习os首先需要引入os文件,imoprt os import os #getcwd()的用法,它是返回当前的工作目录,说白了就是你的程序 ...

  5. 目标检测----ImageAI使用

    1.开源项目  github地址  https://github.com/OlafenwaMoses/ImageAI 2.目标检测(Object Detection)入门概要 3.Pycharm中无法 ...

  6. android checkBox选中与取消

    checkView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO ...

  7. 基于ATT和CK™框架的开放式方法评估网络安全产品

    场景 提供有关如何使用特定商业安全产品来检测已知对手行为的客观见解 提供有关安全产品和服务真实功能的透明度以检测已知的对手行为 推动安全供应商社区增强其检测已知对手行为的能力 地址 https://a ...

  8. Cascade R-CNN论文讲解(转载)

    转载链接:https://blog.csdn.net/qq_21949357/article/details/80046867 论文思想:为了解决IOU设置带来的最终的AP值,作者引入了cascade ...

  9. wxpy: 用 Python 玩微信【转】

    转自:https://wxpy.readthedocs.io/zh/latest/index.html 微信机器人 / 可能是最优雅的微信个人号 API wxpy 在 itchat 的基础上,通过大量 ...

  10. PEP525--异步生成器

    [译] PEP 525--异步生成器 PEP原文:https://github.com/python/peps/blob/master/pep-0525.txt 创建日期:2016-07-18 译者 ...