对于字典树和01字典树的一点理解:
首先,字典树建树的过程就是按照每个数的前缀来的,如果你要存储一个全小写字母字符串,那么这个树每一个节点最多26个节点,这样的话,如果要找特定的单词的话,按照建树的方式找就可以了。
然后是01字典树,这个树在处理一些异或问题的时候特别好用,首先在存储一个树的过程中,我们是按照从高位开始的,如果是对于int型的,我们就从这个数的32位开始存储,不够的话,按照0补,这是建树的过程。再就是查询的时候,对于给定的数,我们先去找这一位上和他不同的,比如说,如果当前这个数的第i位上是1,那我们就找有没有一个数第i位上是0,如果没有的话,再去找第i位是0的数,然后按照从高位到低位寻找的话,就一定能寻找到满足情况的最优解。
入门:
题目链接:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/2828.html
用数组模拟。
我的理解:假设给你n个字符串,我们可以把有相同前缀的按照树的形式存储下来,这样就能够节省很多的空间,然后通过递归的形式来建树或者查找子串是否存在或者存在的次数。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e6+10; 4 char tmp[maxn]; 5 int root[maxn][30]; 6 int top; 7 void init() 8 { 9 for(int i=0; i<top; i++) 10 { 11 for(int j=0; j<30; j++) 12 { 13 root[i][j]=0; 14 } 15 } 16 top=0; 17 } 18 void add(char *str) 19 { 20 int tot=0; 21 int len=strlen(str); 22 for(int i=0; i<len; i++) 23 { 24 int t=str[i]-'a'; 25 if(root[tot][t]==0) 26 root[tot][t]=++top; 27 tot=root[tot][t]; 28 } 29 } 30 bool judge(char *str) 31 { 32 int len=strlen(str); 33 int tot=0; 34 for(int i=0; i<len; i++) 35 { 36 int t=str[i]-'a'; 37 if(root[tot][t]==0) 38 return false; 39 tot=root[tot][t]; 40 } 41 return true; 42 } 43 int main() 44 { 45 int n,m; 46 top=0; 47 while(~scanf("%d %d",&n,&m)&&(n+m)) 48 { 49 init(); 50 for(int i=1; i<=n; i++) 51 { 52 // getchar(); 53 scanf("%s",tmp); 54 add(tmp); 55 // cout<<tmp<<endl; 56 } 57 for(int i=1; i<=m; i++) 58 { 59 // getchar(); 60 scanf("%s",tmp); 61 if(judge(tmp)) 62 printf("Yes "); 63 else 64 printf("No "); 65 } 66 } 67 return 0; 68 }
A题:
题目链接:https://cn.vjudge.net/contest/276901#problem/A
题目大意:先输入若干个字符串,然后再每一次输入一个字符串,问你当前这个字符串再一开始输入的字符串中是前缀的有多少个?
AC代码:
1 #include<iostream> 2 #include<stack> 3 #include<string> 4 #include<cstring> 5 #include<stdio.h> 6 using namespace std; 7 # define ll long long 8 const int maxn = 2e6+100; 9 int rec[maxn][30]; 10 int flag[maxn]; 11 int tot; 12 char str1[maxn]; 13 void add(char *str) 14 { 15 int root=0; 16 int len=strlen(str); 17 for(int i=0; i<len; i++) 18 { 19 int t=str[i]-'a'; 20 if(!rec[root][t]) 21 rec[root][t]=++tot; 22 flag[rec[root][t]]++; 23 root=rec[root][t]; 24 25 } 26 } 27 int judge(char *str) 28 { 29 int root=0; 30 int len=strlen(str); 31 for(int i=0; i<len; i++) 32 { 33 int t=str[i]-'a'; 34 if(rec[root][t]==0) 35 return 0; 36 root=rec[root][t]; 37 //cout<<i<<endl; 38 } 39 return flag[root]; 40 } 41 void init() 42 { 43 for(int i=0; i<tot; i++) 44 { 45 for(int j=0; j<30; j++) 46 { 47 rec[i][j]=0; 48 } 49 } 50 tot=0; 51 } 52 int main() 53 { 54 tot=0; 55 while(gets(str1)) 56 { 57 if(str1[0]=='