Trie树的小应用——Chemist
题意(自己编的):
给你一篇文章,包含n个长度为Si的单词,然后给你m组询问,每次询问一个单词在这篇文章中作为单词前缀出现的次数。n <=10^6,m<=10^6,Si<=100。
还是用字典树,在插入的时候记录每一个节点被访问的次数,在查找的时候用指针p找到当前单词,这个单词的最后一个字母到的节点所存的次数就是它作为前缀出现的次数。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int M=1e6+2; 4 char word[200]; 5 int n,m,trie[M][27],sum=1,tim[M]; 6 void insert(char a[]) 7 { 8 int len=strlen(a),p=1; 9 for(int i=0;i<len;i++) 10 { 11 int ch=a[i]-'a'; 12 if(trie[p][ch]==0)trie[p][ch]=++sum; 13 p=trie[p][ch]; 14 //if(i!=len-1)//如果是严格前缀的话 15 tim[p]++;//tim数组记录每个节点被访问过的次数 16 } 17 } 18 int find(char a[]) 19 { 20 int len=strlen(a),p=1; 21 for(int i=0;i<len;i++) 22 { 23 int ch=a[i]-'a'; 24 p=trie[p][ch]; 25 if(p==0)return 0; 26 } 27 return tim[p]; 28 } 29 int main() 30 { 31 cin>>n>>m; 32 for(int i=1;i<=n;i++) 33 { 34 cin>>word; 35 insert(word); 36 } 37 for(int i=1;i<=m;i++) 38 { 39 cin>>word; 40 printf("%d\n",find(word)); 41 } 42 return 0; 43 }
独立意志与自由思想是必须争的,且须以生死力争。