【题目链接】:
【题意】
我认为这个题目最难的是题意:
其实分了两种情况:
1、如果当前文本串匹配不完,那么答案的是:匹配过程中遇到的模式串结尾的个数 + 文本串结尾 的节点 ,模式串的经过该点的个数。
2、如果是文本串中途遇到问题,而不能继续匹配的情况是:匹配过程中遇到的模式串结尾的个数
只要分开这两种情况即可。
【代码】:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 5e4 ; 6 const int M = 5e4*30; 7 int Son[M][3]; 8 int s[M],Sum[M],End[M]; 9 int n,m,k,idx; 10 void Insert(){ 11 int p = 0 ; 12 for(int i=0;i<k;i++){ 13 if( !Son[p][s[i]] ) Son[p][s[i]] = ++idx; 14 p = Son[p][s[i]]; 15 Sum[p] ++ ; 16 } 17 End[p]++; 18 } 19 void Query(){ 20 int p = 0 , res = 0 ; 21 for(int i=0;i<k;i++){ 22 if( !Son[p][s[i]] ){ 23 printf("%d\n",res); 24 return ; 25 } 26 p = Son[p][s[i]]; 27 res += End[p]; 28 } 29 res = res - End[p] + Sum[p]; 30 printf("%d\n",res); 31 } 32 int main() 33 { 34 scanf("%d%d",&n,&m); 35 for(int i=1;i<=n;i++){ 36 scanf("%d",&k); 37 for(int j=0;j<k;j++) 38 scanf("%d",&s[j]); 39 Insert(); 40 } 41 for(int i=1;i<=m;i++){ 42 scanf("%d",&k); 43 for(int j=0;j<k;j++) 44 scanf("%d",&s[j]); 45 Query(); 46 } 47 return 0; 48 }