01字典树的应用
2019-07-29 16:30
56 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40534166/article/details/97646997
01字典树的应用
01Trie可以快速处理一堆数字
既然trie树比较与字符串亲近,我们就想方设法地把数字转成字符串
没错!就是二进制!
01Trie的应用(1):
给出一个集合,多次询问,每次给出一个数,求这个数和集合中的数的异或的最大值。
根据位运算的性质,高位越大越好。 按照数字的二进制建立 Trie,对于一个询问,从上往下走,贪心的选异或起来更大的方向走,直到走到叶子。
具体实现:
#include<bits/stdc++.h> #define Rep(a,b,c) for(register int a=b;a<=c;a++) #define Mem(d,e) memset(d,e,sizeof(d)) using namespace std; int bits[25],a[300007],cnt=0,opt=0; inline int in(){ int W=1,X=0; char Ch=0; while(!isdigit(Ch)){ if(Ch=='-') W=-1; Ch=getchar(); } while(isdigit(Ch)) X=(X<<3)+(X<<1)+(Ch^'0'),Ch=getchar(); return X*W; } inline void out(int M,char *s){ if(M<0) putchar('-'),M=-M; if(M>9) out(M/10,""); putchar(M%10+'0'); printf(s); return; } inline void getbits(){ bits[0]=1; Rep(i,1,19) bits[i]=bits[i-1]<<1; return; } struct Node{ int son[2],id; }; struct Trie{ Node s[1<<24]; inline void build(){ Mem(s,0),getbits(); } inline void add(int cur,int dep,int x){ if(dep<0) { s[cur].id=x; return; } bool tmp=bits[dep]&x; add(s[cur].son[tmp]=++cnt,dep-1,x); } inline int query(int cur,int dep){ if(dep<0) return s[cur].id; bool tmp=bits[dep]&opt; if(s[cur].son[tmp^1]); return query(s[cur].son[tmp^1],dep-1); return query(s[cur].son[tmp],dep-1); } }A; int main(){ int n,q; n=in(),q=in(); A.build(); Rep(i,1,n) a[i]=in(); sort(a+1,a+n+1); n=unique(a+1,a+n+1)-a-1; while(n) A.add(0,19,a[n--]); while(q--){ opt=in(); out(A.query(0,19),"\n"); } }
应用2——特殊的01Trie
CF842D
题意简述:
维护一个长度为n的序列,每次给出一个x ,请进行如下操作:
1.把序列中的所有数和 x异或
2.查询这个序列的 mex(最小的没有出现过的非负整数)
题目可以等价为:
给出一个集合,多次查询,每次查询给出一个x,问集合中所有数异或上x之后的 mex
建出 0/1 Trie,从上往下走。如果左儿子满了,就递归到右儿子,否则递归到左儿子,直到叶子即为答案。
#include <cstdio> #include <algorithm> using namespace std; int trie[6000005][2], tot = 1, has[6000005]; void insert(int n) { int t = 1; for(int i = 20; i > 0; i--) { has[t]++; if(n & (1 << (i - 1))) { if(!trie[t][1]) trie[t][1] = ++tot; t = trie[t][1]; } else { if(!trie[t][0]) trie[t][0] = ++tot; t = trie[t][0]; } } has[t]++; } int dlt = 0; int query() { int t = 1, res = 0; for(int i = 20; i > 0; i--) { if(dlt & (1 << (i - 1))) { if(!trie[t][1]) { return res; } else if(has[trie[t][1]] < (1 << (i - 1))) { t = trie[t][1]; } else { t = trie[t][0]; res += (1 << (i - 1)); } } else { if(!trie[t][0]) { return res; } else if(has[trie[t][0]] < (1 << (i - 1))) { t = trie[t][0]; } else { t = trie[t][1]; res += (1 << (i - 1)); } } } return res; } int n, m, a[300005], t; int main() { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a + n); n = unique(a, a + n) - a; for(int i = 0; i < n; i++) { insert(a[i]); } for(int i = 0; i < m; i++) { scanf("%d", &t); dlt ^= t; printf("%d\n", query()); } return 0; }
相关文章推荐
- 字典树及其应用
- HDU-2602 Bone Collector(01背包讲解+水题应用)
- php学习01--环境搭建和简单应用
- 使用01字典树解决最大异或问题
- HDU4825(01字典树)
- Chip Factory---hdu5536(异或值最大,01字典树)
- 字典树01
- 字典树简介和简易应用
- 轻量级应用开发之(13)网络简绍-01
- 字典树的应用
- HDU 4825 Xor Sum (01字典树)
- [HDU 4825] Xor Sum(01字典树+贪心)
- 北大ACM2503——Babelfish~~字典树的应用
- Codeforces Round #367 (Div. 2):Vasiliy's Multiset(01字典树)
- QQ互联开发-01-开发者注册和网站应用申请
- hdu 5269 01字典树
- HDU - 6191 Query on A Tree 可持久化字典树(01Trie) || 字典树启发式合并
- bzoj 4260: Codechef REBXOR(01字典树)
- javaweb基础 01--JSP取得绝对路径应用
- 搜索专题01 DFS 简单应用 (深搜剪枝)