YbtOJ 字典树课堂过关 例1 前缀统计【trie树】

在这里插入图片描述


不会字典树就截这里

思路

这道题首先把所有S存进trie树中,然后用一个 v [ i ] v[i] v[i] 来表示以编号为i的节点为结尾的字符串的的个数,
这样就能在统计每个输入的前缀(遍历trie树)时直接累加v数组了。
答案为: ∑ X ∈ T v [ x [ l a s t ] ] \sum_{X\in T} v[x[last]] XTv[x[last]].

代码

#include<iostream>
#include<cstring> 
#include<cstdio>
using namespace std;
int n,m,trie[1000010][27],v[1000010],tot=1;
char s[1000100],c[1000100];
int insert()
{
    
    
	int longs=strlen(s+1),dg=1,c=0;
	for(int i=1; i<=longs; i++)
	 {
    
    
	 	int cc=s[i]-95;
	 	if(!trie[dg][cc])
	 	  trie[dg][cc]=++tot;
	 	dg=trie[dg][cc];
	 }
	v[dg]++;
//	cout<<v[dg]<<" "<<dg<<endl;
}
int sfind()
{
    
    
    int longc=strlen(c+1),dg=1,cc=0;
    int ans=0;
    for(int i=1; i<=longc; i++)
     {
    
    
     	int cc=c[i]-95;
     	if(!trie[dg][cc])
     	  return ans;
     	dg=trie[dg][cc];
     	ans+=v[dg];
//     	cout<<ans<<" "<<v[dg]<<" "<<dg<<endl;
	 }
	return ans;
}
int main()
{
    
    
	cin>>n>>m;
	for(int i=1; i<=n; i++)
	 {
    
    
	 	scanf("%s",s+1);
	 	insert();
	 }
	for(int i=1; i<=m; i++)
	 {
    
    
	 	scanf("%s",c+1);
	 	printf("%d\n",sfind());
	 }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Jackma_mayichao/article/details/115027985
今日推荐