AT_abc353_e 题解

思路

字典树板子题。如果你不会字典树,请右转其它题解。

我们用 tri,jtr_{i,j} 表示从 ii 号节点转移过来且以字母 jj 结尾的节点编号,si,js_{i,j} 表示这种前缀字符串(从 ii 号节点转移过来且以字母 jj 结尾)的个数,我们不管前缀有多长,只需要计算 Csi,j2\sum C_{s_{i,j}}^2 即可,因为最长前缀会在递归遍历时被逐层计算。

代码

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
int n, tot;
ll sum;
string a;
pii tr[300005][30];
void add () {
	int now = 0;
	for (char& i : a) {
		if (! tr[now][i - 'a'].second)
			tr[now][i - 'a'].second = ++ tot;
		++ tr[now][i - 'a'].first;
		now = tr[now][i - 'a'].second;
	}
	return ;
}
void find (int now) {
	for (int i = 0; i < 26; ++ i)
		if (tr[now][i].second)
			sum += tr[now][i].first * (tr[now][i].first - 1ll) / 2, find (tr[now][i].second);
	return ;
}
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> n;
	for (int i = 0; i < n; ++ i)
		cin >> a, add ();
	find (0);
	cout << sum;
	return 0;
}
posted @ 2024-05-16 19:49  Vitamin_B  阅读(11)  评论(0)    收藏  举报  来源