Problem:
Score : 700 points

Problem Statement

Limak can repeatedly remove one of the first two characters of a string,
for example abcxyx \rightarrow acxyx \rightarrow cxyx \rightarrow cyx.

You are given N different strings S_1, S_2, \ldots, S_N.
Among N \cdot (N-1) / 2 pairs (S_i, S_j),
in how many pairs could Limak obtain one string from the other?

Constraints

2 \leq N \leq 200\,000

S_i consists of lowercase English letters a-z.

S_i \neq S_j

1 \leq |S_i|

|S_1| + |S_2| + \ldots + |S_N| \leq 10^6

Input

Input is given from Standard Input in the following format.

N
S_1
S_2
\vdots
S_N

Output

Print the number of unordered pairs (S_i, S_j)
where i \neq j and Limak can obtain one string from the other.

Sample Input 1

3
abcxyx
cyx
abc

Sample Output 1

1

The only good pair is (abcxyx, cyx).

Sample Input 2

6
b
a
abc
c
d
ab

Sample Output 2

5

There are five good pairs: (b, abc), (a, abc), (abc, c), (b, ab), (a, ab).

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;

#[allow(unused_imports)]
use proconio::marker::{Bytes, Chars, Usize1};
#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
#[allow(unused_imports)]
use std::ops::*;
#[derive(Clone, Debug, Default)]
struct Struct;

const MAX_ALPHA:usize = 26;

//#[proconio::fastout]
fn main() {
    input! {
        n: usize,
        mut s: [Bytes;n],
    }

    for i in 0..n {
        s[i].reverse();
    }
    // 末尾の文字を無視してソートする。sliceのcmpは辞書順
    s.sort_unstable_by(|a,b|{a[0..a.len()-1].cmp(&b[0..b.len()-1])}); 

    let mut samelen = Vec::with_capacity(n); // 次の文字列と比べて、先頭何文字が一致するか
    for i in 0..n-1 {
        let mut j = 0;
        let maxlen = min(s[i].len() , s[i+1].len());
        while j < maxlen && s[i][j] == s[i+1][j] {
            j += 1;
        }
        samelen.push(j);
    }

    let mut char_count = vec![vec![0;MAX_ALPHA];n]; // 文字の出現頻度
    for i in 0..n {
        for j in 0..s[i].len() {
            char_count[i][(s[i][j] - b'a') as usize] += 1;
        }
    }

    let mut ans = 0u64;
    for i in 0..n-1 {
        let len1 = s[i].len()-1;
        let lastchar = (s[i][len1] - b'a') as usize;
        for j in i+1 .. n {
            if samelen[j-1] < len1 {
                break;
            }
            if char_count[j][lastchar] >= char_count[i][lastchar] {
                ans += 1;
            }
        }
        //let st = std::str::from_utf8(&s[i][..]).unwrap();
        //println!("{} {}", st, ans );
    }

    println!("{}", ans);
}