【Trie】Secret Message 秘密信息

时间:2023-03-10 05:55:42
【Trie】Secret Message 秘密信息

【题目链接】:

https://loj.ac/problem/10054

【题意】

我认为这个题目最难的是题意:

其实分了两种情况:

1、如果当前文本串匹配不完,那么答案的是:匹配过程中遇到的模式串结尾的个数 + 文本串结尾 的节点 ,模式串的经过该点的个数。

2、如果是文本串中途遇到问题,而不能继续匹配的情况是:匹配过程中遇到的模式串结尾的个数

只要分开这两种情况即可。

【代码】:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 5e4 ;
const int M = 5e4*;
int Son[M][];
int s[M],Sum[M],End[M];
int n,m,k,idx;
void Insert(){
int p = ;
for(int i=;i<k;i++){
if( !Son[p][s[i]] ) Son[p][s[i]] = ++idx;
p = Son[p][s[i]];
Sum[p] ++ ;
}
End[p]++;
}
void Query(){
int p = , res = ;
for(int i=;i<k;i++){
if( !Son[p][s[i]] ){
printf("%d\n",res);
return ;
}
p = Son[p][s[i]];
res += End[p];
}
res = res - End[p] + Sum[p];
printf("%d\n",res);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&k);
for(int j=;j<k;j++)
scanf("%d",&s[j]);
Insert();
}
for(int i=;i<=m;i++){
scanf("%d",&k);
for(int j=;j<k;j++)
scanf("%d",&s[j]);
Query();
}
return ;
}