【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;
}

posted @ 2021-05-14 22:17  Jayun  阅读(58)  评论(0编辑  收藏  举报