8.1每日一题
P10470 前缀统计 - 洛谷
题目描述
给定 N 个字符串 S1,S2⋯SN,接下来进行 M 次询问,每次询问给定一个字符串 T,求 S1∼SN 中有多少个字符串是 T 的前缀。
输入字符串的总长度不超过 106,仅包含小写字母。
输入格式
第一行输入两个整数 N,M。
接下来 N 行每行输入一个字符串 Si。
接下来 M 行每行一个字符串 T 用以询问。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
输入输出样例
输入 #1复制
3 2 ab bc abc abc efg
输出 #1复制
2 0
说明/提示
数据范围满足 1≤N,M≤105
经典的trie板子。
做一个trie树就好了,看代码
#include<bits/stdc++.h>
using namespace std;
struct trid
{int end;//end的数量int next[30];//指向下一个的索引
}node [1000000];
int cnt = 1;
void add(string s)//插入一个字符串
{int len = s.length();int now = 0;for (int i = 0; i < len; i++){if(!node[now].next[s[i] - 'a'])//看看是否建立了这个索引node[now].next[s[i] - 'a'] = cnt++;//指向下一个索引now = node[now].next[s[i] - 'a'];}node[now].end++;
}
void find(string s)//寻找前缀有多少个
{int len = s.length();int now = 0;int ans = 0;for (int i = 0; i < len; i++){if (node[now].next[s[i] - 'a'])now = node[now].next[s[i] - 'a'];elsebreak;ans += node[now].end;}cout << ans << endl;
}
int main()
{int n, m;cin >> n >> m;string s;for (int i = 0; i < n; i++){cin >> s;add(s);}for (int i = 0; i < m; i++){cin >> s;find(s);}return 0;
}