E - Yet Another Sigma Problem Editorial by en_translator
This problem can be solved with a data structure called Trie.
The length of the longest common prefix of \(S_i\) and \(S_j\) equals the number of common prefixes of \(S_i\) and \(S_j\). For example, the longest common prefix of abc
and abde
has a length of two, and they have two common prefixes a
and ab
.
Thus, it is sufficient to enumerate all prefixes \(T\) of \(S_j\) for all \(S_j\), and count the number of \(S_i\ (1\leq i < j)\) that has \(T\) as its suffix.
This can be done by inserting \(S_i\) in a Trie for each \(i=1,2,\ldots,N\) in order, each of whose node manages the number of strings that has the string represented by the node as a suffix.
Sample code (C++):
#include <bits/stdc++.h>
using namespace std;
struct trie {
using ar = array<int, 26>;
vector<ar> pos;
ar def;
int now_sz;
long long ans;
vector<int> cnt;
trie() = default;
trie(int len) {
pos.reserve(len + 1);
cnt.reserve(len + 1);
def.fill(-1);
now_sz = ans = 0;
make_node();
}
int make_node() {
pos.push_back(def);
cnt.push_back(0);
return now_sz++;
}
void add(string &s) {
int now = 0;
for(int i = 0; i < (int)s.size(); i++) {
int d = s[i] - 'a';
int &nx = pos[now][d];
if(nx == -1)
nx = make_node();
now = nx;
ans += cnt[now]++;
}
}
};
int main() {
int n;
cin >> n;
trie tr(300000);
for(int i = 0; i < n; i++) {
string s;
cin >> s;
tr.add(s);
}
cout << tr.ans << endl;
}
posted:
last update: