Language: C++

#pragma region header
// #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define all(a) begin(a), end(a)
#define rall(a) rbegin(a), rend(a)
#define mp make_pair
#define mt make_tuple
#define rep1(i, n) for (decltype(+n) i = 0; i < (n); i++)
#define rrep1(i, n) for (auto i = n - 1; i > static_cast<decltype(i)>(-1); i--)
#define rep2(i, a, b) for (auto i = (a); i < (b); i++)
#define rrep2(i, a, b) for (auto i = b - 1; i >= a; i--)
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define rep(...) GET_MACRO(__VA_ARGS__, rep2, rep1) (__VA_ARGS__)
#define rrep(...) GET_MACRO(__VA_ARGS__, rrep2, rrep1) (__VA_ARGS__)
#define each(i, a) for (auto &&i : (a))
using namespace std;

using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;
using vvs = vector<vs>;
using vd = vector<ld>;
using vvd = vector<vd>;
using vb = vector<bool>;
using vvb = vector<vb>;
using pii = pair<int, int>;
using vp = vector<pii>;
using vvp = vector<vp>;
using mii = map<int, int>;
using vm = vector<mii>;
using vvm = vector<vm>;
template <class T, class U>
using umap = unordered_map<T, U>;
using umii = umap<int, int>;
using seti = set<int>;
template <class T>
using uset = unordered_set<T>;
using useti = uset<int>;
template <class T>
using less_queue = priority_queue<T>;
template <class T>
using greater_queue = priority_queue<T, vector<T>, greater<T>>;

template <class T>
void SORT(T &a) { stable_sort(all(a)); }
template <class T>
void RSORT(T &a) { stable_sort(rall(a)); }
template <class T>
void rev(T &a) { reverse(rall(a)); }
template <class T>
void uniq(T &a) { a.erase(unique(all(a)), end(a)); }
template <class T>
auto min_of(T a) { return *min_element(all(a)); }
template <class T>
auto max_of(T a) { return *max_element(all(a)); }
template <class T>
int sum_of(T a) { return accumulate(all(a), 0ll); }
template <class T, class U>
auto sum_of(T a, U init) { return accumulate(all(a), init); }
template <class T, class U>
int count_of(T a, U i) { return count(all(a), i); }
template <class T, class U>
bool has(T a, U i) { return find(all(a), i) != end(a); }
template <class T>
int sz(T a) { return a.size(); };

template <class T>
void COUT(T x) { cout << x << endl; }
template <class T, class U>
void COUT(T x, U y) { cout << x << ' ' << y << endl; }
template <class T, class U, class V>
void COUT(T x, U y, V z) { cout << x << ' ' << y << ' ' << z << endl; }
template <class T>
void CSP(T x) { cout << x << ' '; }
template <class T>
void CVEC(T v) {
  int c = v.size() - 1;
  for (size_t i = 0; i < c; i++) cout << v[i] << ' ';
  if (c > -1) cout << v[c];
  cout << endl;
}

template <class T>
bool amin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool amax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

constexpr int lshift(int x) noexcept { return 1ll << x; }
constexpr int popcount(unsigned int x) noexcept { return __builtin_popcountll(x); }
constexpr int least1(unsigned int x) noexcept { return __builtin_ffsll(x); }
constexpr int ceil_div(int x, int y) noexcept { return (x - 1) / y + 1; }

#pragma endregion header

struct rolling_hash {
  static const uint64_t mod = (1ull << 61ull) - 1;
  using uint128_t = __uint128_t;
  vector<uint64_t> hashed;
  static vector<uint64_t> power;
  const uint64_t base;

  static inline uint64_t add(uint64_t a, uint64_t b) {
    if ((a += b) >= mod) a -= mod;
    return a;
  }

  static inline uint64_t mul(uint64_t a, uint64_t b) {
    uint128_t c = (uint128_t)a * b;
    return add(c >> 61, c & mod);
  }

  static inline uint64_t generate_base() {
    mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
    uniform_int_distribution<uint64_t> rand(1, rolling_hash::mod - 1);
    return rand(mt);
  }

  static void init_power(size_t sz, uint64_t base) {
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) power[i + 1] = mul(power[i], base);
  }

  rolling_hash() = default;

  rolling_hash(const string &s, uint64_t base) : base(base) {
    size_t sz = s.size();
    hashed.assign(sz + 1, 0);
    for (int i = 0; i < sz; i++) {
      hashed[i + 1] = add(mul(hashed[i], base), s[i]);
    }
  }

  template <typename T>
  rolling_hash(const vector<T> &s, uint64_t base) : base(base) {
    size_t sz = s.size();
    hashed.assign(sz + 1, 0);
    for (int i = 0; i < sz; i++) {
      hashed[i + 1] = add(mul(hashed[i], base), s[i]);
    }
  }

  uint64_t query(int l, int r) const {
    return add(hashed[r], mod - mul(hashed[l], power[r - l]));
  }

  uint64_t combine(uint64_t h1, uint64_t h2, size_t h2len) const {
    return add(mul(h1, power[h2len]), h2);
  }

  int lcp(const rolling_hash &b, int l1, int r1, int l2, int r2) const {
    assert(base == b.base);
    int len = min(r1 - l1, r2 - l2);
    int low = 0, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (query(l1, l1 + mid) == b.query(l2, l2 + mid)) low = mid;
      else high = mid;
    }
    return low;
  }
};
/*
auto rh_base = rolling_hash::generate_base();
rolling_hash::init_power(1000000, rh_base);
*/

void solve(int n, vector<string> s) {
  vector<pair<int, string>> ls(n);
  rep(i, n)ls[i] = mp(sz(s[i]), s[i]);
  SORT(ls);
  vector<map<u_int64_t, int>> hs(26);
  auto rh_base = rolling_hash::generate_base();
  rolling_hash::init_power(1000000, rh_base);
  int ans = 0;
  each(p, ls) {
    auto [l, x] = p;
    rolling_hash rh(x, rh_base);
    vb cm(26);
    rep(i, p.first) {
      cm[x[i] - 'a'] = true;
      auto h = rh.query(i + 1, l);
      rep(j, 26) {
        if(cm[j])ans += hs[j][h];
      }
    }
    hs[x[0] - 'a'][rh.query(1, l)]++;
  }
  COUT(ans);
}


#pragma region main
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed << setprecision(15);

  int n;
  cin >> n;
  vector<string> s(n);
  for(int i = 0 ; i < n ; i++){
    cin >> s[i];
  }
  solve(n, move(s));
}
#pragma endregion main


Compiler output:
/usr/bin/ld: /tmp/ccsiAaZe.o: warning: relocation against `_ZN12rolling_hash5powerE' in read-only section `.text._ZNK12rolling_hash5queryEii[_ZNK12rolling_hash5queryEii]'
/usr/bin/ld: /tmp/ccsiAaZe.o: in function `rolling_hash::init_power(unsigned long, unsigned long)':
a.cc:(.text._ZN12rolling_hash10init_powerEmm[_ZN12rolling_hash10init_powerEmm]+0x2e): undefined reference to `rolling_hash::power'
/usr/bin/ld: a.cc:(.text._ZN12rolling_hash10init_powerEmm[_ZN12rolling_hash10init_powerEmm]+0x42): undefined reference to `rolling_hash::power'
/usr/bin/ld: a.cc:(.text._ZN12rolling_hash10init_powerEmm[_ZN12rolling_hash10init_powerEmm]+0x69): undefined reference to `rolling_hash::power'
/usr/bin/ld: a.cc:(.text._ZN12rolling_hash10init_powerEmm[_ZN12rolling_hash10init_powerEmm]+0x98): undefined reference to `rolling_hash::power'
/usr/bin/ld: /tmp/ccsiAaZe.o: in function `rolling_hash::query(int, int) const':
a.cc:(.text._ZNK12rolling_hash5queryEii[_ZNK12rolling_hash5queryEii]+0x21): undefined reference to `rolling_hash::power'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status