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)

#![allow(unused_imports)]
#![allow(unused_macros)]
use std::cell::{RefCell, RefMut};
use std::cmp::{max, min};
use std::collections::*;
use std::io::{stdin, Read};

#[allow(unused_macros)]
macro_rules! parse {
    ($it: ident ) => {};
    ($it: ident, ) => {};
    ($it: ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = parse_val!($it, $t);
        parse!($it $($r)*);
    };
    ($it: ident, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = parse_val!($it, $t);
        parse!($it $($r)*);
    };
    ($it: ident, $var:ident $($r:tt)*) => {
        let $var = parse_val!($it, usize);
        parse!($it $($r)*);
    };
}

#[allow(unused_macros)]
macro_rules! parse_val {
    ($it: ident, [$t:tt; $len:expr]) => {
        (0..$len).map(|_| parse_val!($it, $t)).collect::<Vec<_>>();
    };
    ($it: ident, ($($t: tt),*)) => {
        ($(parse_val!($it, $t)),*)
    };
    ($it: ident, u1) => {
        $it.next().unwrap().parse::<usize>().unwrap() -1
    };
    ($it: ident, $t: ty) => {
        $it.next().unwrap().parse::<$t>().unwrap()
    };
}

#[cfg(debug_assertions)]
macro_rules! debug {
    ($( $args:expr ),*) => { eprintln!( $( $args ),* ); }
}

#[cfg(not(debug_assertions))]
macro_rules! debug {
    ($( $args:expr ),*) => {
        ()
    };
}

const l: usize = 26;

#[derive(Default, Debug)]
struct Node {
    is_leaf: bool,
    nleafs: usize,
    counts: [usize; l],
    children: BTreeMap<u8, Box<Node>>,
    seen: bool,
}

fn add_count(node: &mut Node) {
    for (k, v) in &mut node.children {
        add_count(v);
        let vn = v.nleafs + if v.is_leaf { 1 } else { 0 };
        node.nleafs += vn;
        for i in 0..l {
            if i != *k as usize {
                node.counts[i] += v.counts[i];
            } else {
                node.counts[i] += vn;
            }
        }
    }
}

fn count(node: &Node) -> usize {
    let mut ret = 0;
    for (k, v) in &node.children {
        if v.is_leaf {
            let pret = node.counts[*k as usize] - 1;
            ret += pret;
            if pret > 0 {
                // debug!("{:?} {:?}", (k, pret), node); // DEBUG
            }
        }
        ret += count(v);
    }
    ret
}

fn solve(s: &str) {
    let mut it = s.split_whitespace();
    parse!(it, n: usize);
    let mut root = Node {
        is_leaf: false,
        counts: [0; 26],
        children: BTreeMap::new(),
        nleafs: 0,
        seen: false,
    };
    for _ in 0..n {
        let s: Vec<_> = it.next().unwrap().bytes().rev().collect();
        let mut cur = &mut root;
        for (i, c) in s.iter().enumerate() {
            let k = c - b'a';
            cur = cur.children.entry(k).or_default();
            if i == s.len() - 1 {
                cur.is_leaf = true;
            }
        }
    }
    add_count(&mut root);
    assert_eq!(root.nleafs, n);
    debug!("{:?}", root); // DEBUG
    println!("{}", count(&root));
}

fn main() {
    let mut s = String::new();
    stdin().read_to_string(&mut s).unwrap();
    solve(&s);
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_input() {
        let s = "
        ";
        solve(s);
    }
}