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

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

/*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. DIY一些基于netty的开源框架

    几款基于netty的开源框架,有益于对netty的理解和学习! 基于netty的http server框架 https://github.com/TogetherOS/cicada 基于netty的即 ...

  2. mysql 开源 ~ canal+otter系列(1)

    一 简介: 今天咱们来聊聊 canal和otter的组合搭配吧二 概念统计   1. 基于Canal开源产品,获取数据库增量日志数据.   2. 典型管理系统架构,manager(web管理)+nod ...

  3. mysql 案例 ~ insert插入慢的场景

    一简介: insert出现慢日志中,应该怎么检测呢 二 理解:事务提交延迟,一般出现在写日志延迟的情况下,会有几种可能    场景:    1 RR模式下,insert等待gap lock锁导致的  ...

  4. Thymeleaf在前台下拉列表获取后台传的值

    Thymeleaf在前台下拉列表获取后台传的值 后台添加代码: /** * 新增机构 */ @GetMapping("/add") public String add(ModelM ...

  5. Debian 9 strech 安装 ROS lunar

    1. 配置源 按照我以前的博客配置或者按照wiki上的配置. 2. sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(ls ...

  6. PHP连接MySQL查询中文时显示Notice: Trying to get property of non-object

    1.保证MySQL和PHP的编码一致 MySQL 修改整个数据库的编码格式     注意:如果数据不重要的话,可以直接使用更改数据库的编码格式,再重新建表即可.(此例中的数据库是test) alter ...

  7. Houdini OpenCL

    SOP: simple moveKernel #include "interpolate.h" float lerpConstant( constant float * in, i ...

  8. 709. To Lower Case

    Algorithm to-lower-case https://leetcode.com/problems/to-lower-case/ 1)problem Implement function To ...

  9. git-bisect last updated in 2.19.1【转】

    转自:https://git-scm.com/docs/git-bisect NAME git-bisect - Use binary search to find the commit that i ...

  10. HAProxy详解(二):HAProxy基础配置与应用实例

    一.HAProxy基础配置与应用实例: 1.快速安装HAProxy集群软件: HAProxy的官网: https://www.haproxy.org/#down下载HAProxy的源码包. 安装: [ ...