cf842D 01字典树|线段树 模板见hdu4825
一般异或问题都可以转换成字典树的问题,,我一开始的想法有点小问题,改一下就好了
下面的代码是逆向建树的,数据量大就不行
/*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的更多相关文章
- 浅谈树套树(线段树套平衡树)&学习笔记
0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...
- 线段树--线段树【模板1】P3372
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含 ...
- Hihocoder #1077 : RMQ问题再临-线段树(线段树:结构体建树+更新叶子往上+查询+巧妙使用father[]+线段树数组要开大4倍 *【模板】)
#1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并 ...
- HDU 5649 DZY Loves Sorting(二分答案+线段树/线段树合并+线段树分割)
题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \le ...
- 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新
目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...
- [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)
解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...
- 「BZOJ3065」带插入区间第K小值 替罪羊树×线段树
题目描述 从前有\(n\)只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力\(a_i\).跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间\(k\)小值.他 ...
- 「BZOJ3600」没有人的算术 替罪羊树+线段树
题目描述 过长--不想发图也不想发文字,所以就发链接吧-- 没有人的算术 题解 \(orz\)神题一枚 我们考虑如果插入的数不是数对,而是普通的数,这就是一道傻题了--直接线段树一顿乱上就可以了. 于 ...
- 权值线段树&线段树合并
权值线段树 所谓权值线段树,就是一种维护值而非下标的线段树,我个人倾向于称呼它为值域线段树. 举个栗子:对于一个给定的数组,普通线段树可以维护某个子数组中数的和,而权值线段树可以维护某个区间内数组元素 ...
随机推荐
- 百度地图API的应用
做网页的时候,有时候需要有地图的功能.接下来我来记录一下我的做法. 1.引入API秘钥,在网上都可以搜到. <script src="http://api.map.baidu.com/ ...
- HDFS笔记(二)
fsimage : NameNode启动时,对文件系统的快照 eidt logs : NameNode启动后,对文件系统的改动序列 namenode在全局里就一个进程,所以存在单点问题 DataNod ...
- zabbix系列 ~ 自动监控多实例功能
一 场景 监控mongo的多实例端口二 目标 定制一套模板,根据不同的端口进行批量监控项的生成三 步骤 1 编写py脚本实现端口josin化输出,以便zabbix_server能进行识别 ...
- python scrapy 报错 DEBUG: Ignoring response 403
DEBUG: Ignoring response <403 http://movie.douban.com/top250>: HTTP status code is not handled ...
- js 一个对象的属性名是一个变量怎么处理?
1.这种方法的属性(setAttrName)可以是一个变量. var obj = {}; obj[setAttrName] = 'Tom' 2.这样就可以动态的给js对象添加变量属性. var obj ...
- 20165237 2017-2018-2 《Java程序设计》第3周学习总结
20165237 2017-2018-2 <Java程序设计>第3周学习总结 教材学习内容总结 1.面向机器语言:类如汇编语言. 2.面向过程语言:类如C语言(但是相当于说话缺少主语). ...
- 第三节,CNN案例-mnist手写数字识别
卷积:神经网络不再是对每个像素做处理,而是对一小块区域的处理,这种做法加强了图像信息的连续性,使得神经网络看到的是一个图像,而非一个点,同时也加深了神经网络对图像的理解,卷积神经网络有一个批量过滤器, ...
- 安卓虚拟机与Hyper-V冲突
经过各种经验,哪个安卓虚拟机跟Hyper-V都存在着冲突. 解决方案一 程序中卸载Hyper-V,之后还要再配置太麻烦. 解决方案二 1.关掉Hyper-V的启动项,命令如下. bcdedit /se ...
- AviSynth AVS Importer Plugin for Adobe Premiere Pro CC 2015 x64
Premiere CS AVS Importer x64.prm copy to Adobe\Adobe Premiere Pro CC 2015\Plug-Ins\Common\ VSFilterM ...
- 缓存系列之五:通过codis3.2实现redis3.2.8集群的管理
通过codis3.2实现redis3.2.8集群 一:Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没 ...