【YBTOJ】前缀统计
题目大意:
给定 \(N\) 个字符串 \(S_1,S_2…S_N\),接下来进行 \(M\) 次询问,每次询问给定一个字符串 \(T\),求 \(S_1 \sim S_N\) 中有多少个字符串是 \(T\) 的前缀。
正文:
Trie 板子。
代码:
const int N = 1e6 + 10;
inline ll READ()
{
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
struct Trie
{
int t[N][30], tot = 0;
bool End[N];
void Insert(char *s)
{
int len = strlen(s + 1), x = 0;
for (int i = 1; i <= len; i++)
{
int ch = s[i] - 'a' + 1;
if (!t[x][ch]) t[x][ch] = ++tot;
x = t[x][ch];
}
End[x]++;
}
int Query(char *s)
{
int len = strlen(s + 1), x = 0, ans = 0;
for (int i = 1; i <= len; i++)
{
int ch = s[i] - 'a' + 1;
if (!t[x][ch]) return ans;
x = t[x][ch];
ans += End[x];
}
return ans;
}
}t;
char s[N];
int n, m, ans;
int main()
{
n = READ(), m = READ();
for (int i = 1; i <= n; i++)
{
scanf ("%s", s + 1);
t.Insert(s);
}
for (; m--; )
{
scanf ("%s", s + 1);
printf ("%d\n", t.Query(s));
}
return 0;
}