【Trie】L 语言

【题目链接】:

https://loj.ac/problem/10053

【题意】:

给出n个模式串。请问文本串是由多少个模式串组成的。

【题解】:

当我学完AC自动机后,发现这个题目也太简单了吧.

不过当时我还是不会,后来看了看洛谷有位大佬的题解。

简直醍醐灌顶。纯Trie树也能写出这个题来。

就是把对应的位置标记上,好比dp的转移。

这个转移是,开一个Mark数组,看看文本串中哪个位置能通过这些模式串匹配出来的。

然后一直转移即可。

【代码】:

 1 //L语言
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N = 3e4 ;
 7 const int M = 3e4 * 26;
 8 const int LEN = 2e6;
 9 int Son[M][26],idx;
10 bool cnt[M];
11 bool Mark[LEN];
12 char s[LEN];
13 int n,m;
14 void Insert(){
15     int p = 0 ;
16     for(int i=0;s[i];i++){
17         int t = s[i]-'a';
18         if( !Son[p][t] ) Son[p][t] = ++idx;
19         p = Son[p][t];
20     }
21     cnt[p] = true;
22 }
23 void Query(){
24     memset( Mark , false , sizeof Mark );
25     int p = 0 ;
26     for(int i=0;s[i];i++){
27         int t = s[i] - 'a';
28         if ( !Son[p][t] ) break;
29         p = Son[p][t];
30         if( cnt[p] ) Mark[i] = true;
31     }
32 
33     int ans = 0 ;
34     for(int i=0 ; s[i] ; i++ ){
35         if( !Mark[i] )  continue;
36         else ans = i+1 ;
37         p = 0 ;
38         for(int j=i+1;s[j];j++){
39             int t = s[j] - 'a';
40             if ( !Son[p][t] ) break;
41             p = Son[p][t];
42             if( cnt[p] ) Mark[j] = true;
43         }
44     }
45     printf("%d
",ans);
46 }
47 int main()
48 {
49     scanf("%d%d",&n,&m);
50     for(int i=0;i<n;i++){
51         scanf("%s",s);
52         Insert();
53     }
54     for(int i=0;i<m;i++){
55         scanf("%s",s);
56         Query();
57     }
58     return 0;
59 }
View Code
原文地址:https://www.cnblogs.com/Osea/p/11361514.html