#trie#洛谷 2922 秘密消息 Secret Message

本文介绍了一种使用Trie树进行字符串前缀匹配的方法,通过构建Trie树并利用节点上的end标记和sum计数来高效判断一组字符串是否为另一组字符串的前缀。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

有几个字符串,现给出一些字符串SSSSSS是否为字符串的前缀或字符串是SSS的前缀


分析

可以用end标记末尾,用sum表示有多少字符串经过该点
然后建trie就好了


代码

#include <cstdio>
int n,m,k,tot,trie[500001][2],end[500001],sum[500001];
int in(){
	int ans=0; char c=getchar();
	while (c<48||c>57) c=getchar();
	while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
	return ans;
}
void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
int main(){
	n=in(); m=in();
	while (n--){
		k=in(); int p=0,x;
		for (register int i=1;i<=k;i++){
			x=in();
			if (!trie[p][x]) trie[p][x]=++tot;
			p=trie[p][x]; sum[p]++;
		}
		end[p]++;
	}
	while (m--){
		k=in(); int p=0,x,ans=0; bool flag=0;
		for (register int i=1;i<=k;i++){
			x=in(); p=trie[p][x];
			if (!p) flag=1; if (!flag) ans+=end[p];
		}
		if(!flag) ans+=sum[p]-end[p];//未终止
		if (ans) print(ans); else putchar('0');
		putchar('\n');
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值