给定N个字符串S1,S2…SNS1,S2…SN,接下来进行M次询问,每次询问给定一个字符串T,求S1S1~SNSN中有多少个字符串是T的前缀。
输入字符串的总长度不超过106106,仅包含小写字母。
输入格式
第一行输入两个整数N,M。
接下来N行每行输入一个字符串SiSi。
接下来M行每行一个字符串T用以询问。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
输入样例:
3 2
ab
bc
abc
abc
efg
输出样例:
2
0
题意:让你计算前面有多少个字符串是查询的这个字符串的前缀思路:这是字符串的题,在字符串算法中和前缀有关的是字典树,模板中是计算这个串是多少个串的前缀,其实这题大同小异,我们在前面插入的时候最后那个节点才加一,然后查询时直接加上沿途所有的值
#include<bits/stdc++.h> #define maxn 1000005 #define mod 1000000007 using namespace std; typedef long long ll; ll n,m; char str[maxn]; ll tree[maxn][26]; ll sum[maxn]; ll top; void insert(){ int len=strlen(str); ll root=0; for(int i=0;i<len;i++){ ll x=str[i]-‘a‘; if(!tree[root][x]) tree[root][x]=++top; root=tree[root][x]; } sum[root]++;//因为是要计算有多少个字符串是查询的前缀就只能当前节点加一了 } ll query(){ ll num=0; ll root=0; for(int i=0;str[i]!=‘\0‘;i++){ ll x=str[i]-‘a‘; if(!tree[root][x]) return num; root=tree[root][x]; num+=sum[root];//加上以当前节点结尾的字符串个数 } return num; } int main(){ scanf("%lld%lld",&n,&m); for(int i=0;i<n;i++){ scanf("%s",str); insert(); } for(int j=0;j<m;j++){ scanf("%s",str); cout<<query()<<"\n"; } }
原文地址:https://www.cnblogs.com/Lis-/p/10896359.html
时间: 2024-10-03 00:54:15