Trie 字典树

~~ 比 KMP 简单多了,无脑子选手学不会KMP,不会结论题~~

自己懒得造图了OI WIKI 真棒

字典树大概长这么个亚子



呕吼真棒

  1. 就是将读进去的字符串根据当前的字符是什么和所处的位置构成一棵树
  2. 例如图中\(1-->2-->5\)这一条路就是字符串\(aa\)那\(1-->4-->8-->13\)就是字符串\(cab\)

    貌似也没有什么东西的,题目的话基本就是套板子,唯一奇怪的就是把一个数二级化建树跑一些奇奇怪怪的东西

字符串:

struct Trie{
int trie[][] ,Trie_num;
void add(char *s){
int now = 0 ,
for(int i = 1 ; i <= len ;i++) {
if(!trie[now][s[i]]) trie[now][s[i]] = +++Trie_num;
now = trie[now][s[i]];
}
}
}

二进制:

struct Trie{
int tire[][] ,Tire_num;
void add(int x){
int now = 0 ,
for(int i = 31 ; i >= 0 ;i--) {
int ch = (x>>(i)&1);
if(!tire[now][ch]) tire[now][ch] = +++Trie
now = tire[now][ch];
}
}
}

踹树的时间复杂度其实不低普遍为\(\sum\limits_{i = 1}^{n}~|s_i|\)

例题

题目洛谷也有

这个题就是很显然的板子

  • 询问输入字符串是否为已经输入串的子串
  • 直接边建树边查询就OK

建树并查询的时候会有2种情况

  1. 一直没有添加新的字母一直到该字符的最后一个,说明该字符串为已加入串的子串
  2. 遍历到了某个字符串的最后一个字符,说明已经添加子串为该字符串的子串

然后就没有然后了,你就把它切了(多测不清我是sb)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
const int N = 1e6+100;
int read() {
int s = 0 , f = 0 ; char ch = getchar() ;
while(!isdigit(ch)) f |= (ch == '-') , ch = getchar();
while(isdigit(ch)) s = s * 10 + (ch ^ 48) , ch = getchar();
return f ? -s : s;
}
char s[20];
struct Trie{
int Tir_num ,tir[N][11],vis[N];
int add(char *s) {
int len = strlen(s+1), now = 0;
bool flag = 0;
for(int i = 1 ; i <= len ;i++) {
int ch = s[i]-'0';
if(!tir[now][ch]) tir[now][ch] = ++Tir_num;
else if(i == len) flag = 1;
// cout << Tir_num<<" ";
now = tir[now][ch];
if(vis[now]) flag = 1;
// cout <<now<<" "<< flag <<" ";
}
vis[now] = 1;
// puts("");
return flag;
}
void clear(){
memset(tir,0,sizeof(tir));
memset(vis,0,sizeof(vis));
Tir_num = 0;
// puts("LKP AK IOI");
}
}tire;
int main() {
int T = read() ;
while(T--) {
tire.clear();
int n = read();
int cnt = 0;
for(int i = 1 ; i <= n;i++){
scanf("%s", s+1);
cnt += tire.add(s);
}
if(cnt) puts("NO");
else puts("YES");
}
system("pause");
return 0;
}

二进制的例题

  • 根据\(xor\)的性质考虑贪心
  • \(1\)^\(1\) \(=0~~\) \(0\) ^ \(1 = 1\) \(~~~~0\) ^ \(0 = 1\)
  • 尽可能的让二级制下的高位存在1

    那么按照这个贪心思路
void query(int x) {
int now = 0 , ans = 0;
for(int i = 31 ; i >= 0 ;i-- ) {
int ch = ((x >> i) & 1) , temp = ch ^ 1;
if(tir[now][temp])
now = tir[now][temp] ,
ans = ((ans << 1) | 1);
else {
now = tir[now][ch];
ans <<= 1;
}
}
return ans;
}

还是贴一下完整代码吧

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
const int N = 4000010;
int read() {
int s = 0 , f = 0 ; char ch = getchar() ;
while(!isdigit(ch)) f |= (ch == '-') , ch = getchar();
while(isdigit(ch)) s = s * 10 + (ch ^ 48) , ch = getchar();
return f ? -s : s;
}
struct Trie{
int tire[N][2], Tir_num;
void add(int x) {
int now = 0 ;
for(int i = 31 ; i >= 0 ;i--) {
int ch = ((x>>i) & 1);
if(!tire[now][ch]) tire[now][ch] = ++Tir_num;
now = tire[now][ch];
}
}
int query(int x){
int now = 0 , ans = 0;
for(int i = 31 ; i >= 0 ;i--) {
int ch = ( (x >> i) & 1) , temp = ch ^ 1;
if(tire[now][temp]) now = tire[now][temp],ans = (ans << 1) | 1;
else now = tire[now][ch], ans <<= 1;
}
return ans;
}
}tir; int a[N];
int main() {
int n = read();
int ans = -1;
for(int i = 1 ; i <= n ;i++) {
a[i] = read();
tir.add(a[i]);
ans = max(ans,tir.query(a[i]));
}
printf("%d",ans);
system("pause");
return 0;
}

踹树能做的AC自动机也能干,好吧Tire树AC自动机的一部分

自己说的仅仅是一部分,OI wiki讲的很详细,对题目分类讲的也很详细,觉得我写的不好可以去OI wiki

最新文章

  1. 【 2013 Multi-University Training Contest 8 】
  2. Hibernate3 和Hibernate4 在配置文件上的区别
  3. xcode5.1+osx.10.9编译x264的问题
  4. js 面试题
  5. spring mvc中的文件上传
  6. [HIHO1143]骨牌覆盖问题&#183;一(矩阵快速幂,递推)
  7. jquery响应回车事件
  8. 关于MDK中:RO-data、RW-data、ZI-data
  9. Struts数据效验
  10. c语言 (linux下)
  11. @PostConstruct 和 @PreDestory
  12. MYSQL数据库表按月备份,滚动,保留6次备份
  13. 【转载】java 中 String s = new String(&quot;abc&quot;) 创建了几个对象?!
  14. c/c++ 多线程 等待一次性事件 packaged_task用法
  15. android使用smack实现简单登录功能
  16. 如何在C#中使用Dapper(译)
  17. 《转》return *this和 return this有什么区别?
  18. Linux系统开发之路-中
  19. 从composer上在本地创建一个项目
  20. Python和Java编程题(四)

热门文章

  1. 简述java多态
  2. python图片的读取保存
  3. java的多线程:线程基础
  4. 大厂面试官竟然这么爱问Kafka,一连八个Kafka问题把我问蒙了?
  5. 【JavaWeb】JSON 文件
  6. 搭建docker环境,安装常用应用(单机)
  7. RecyclerView 源码分析(一) —— 绘制流程解析
  8. 【Oracle】静默安装oracle 11.2.0.4 超详细
  9. 爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法
  10. LeetCode559.N 叉树的最大深度