Official

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: