题目链接:Yong Zheng’s Death
#include <bits/stdc++.h>
using namespace std ;
typedef long long LL ;
#define clr( a , x ) memset ( a , x , sizeof a )
const int MAXN = 300005 ;
int nxt[MAXN][26] ;
int word[MAXN] ;
int lens[MAXN] ;
int fail[MAXN] ;
int Q[MAXN] , head , tail ;
char s[MAXN] ;
int cur ;
int n ;
LL dp[33][MAXN] , ans ;
int newnode ( int i ) {
clr ( nxt[cur] , 0 ) ;
word[cur] = 0 ;
lens[cur] = i + 1 ;
dp[0][cur] = 0 ;
return cur ++ ;
}
void insert ( char s[] , int n ) {
int now = 0 ;
for ( int i = 0 ; i < n ; ++ i ) {
int x = s[i] - 'a' ;
if ( nxt[now][x] == 0 ) nxt[now][x] = newnode ( i ) ;
now = nxt[now][x] ;
}
word[now] = 1 ;
}
void build () {
head = tail = 0 ;
for ( int i = 0 ; i < 26 ; ++ i ) {
if ( nxt[0][i] ) {
Q[tail ++] = nxt[0][i] ;
fail[nxt[0][i]] = 0 ;
} else nxt[0][i] = 0 ;
}
while ( head != tail ) {
int u = Q[head ++] ;
if ( fail[u] ) ++ ans ;
for ( int i = 0 ; i < 26 ; ++ i ) {
if ( nxt[u][i] ) {
fail[nxt[u][i]] = nxt[fail[u]][i] ;
Q[tail ++] = nxt[u][i] ;
} else {
nxt[u][i] = nxt[fail[u]][i] ;
if ( nxt[u][i] ) {
++ ans ;
dp[0][nxt[u][i]] ++ ;
}
}
}
}
}
void solve () {
cur = 0 ;
newnode ( -1 ) ;
int m = 0 ;
for ( int i = 0 ; i < n ; ++ i ) {
scanf ( "%s" , s ) ;
int l = strlen ( s ) ;
insert ( s , l ) ;
m = max ( m , l ) ;
}
ans = 0 ;
build () ;
for ( int i = 1 ; i <= m ; ++ i ) {
for ( int j = 0 ; j < cur ; ++ j ) {
dp[i][j] = dp[i][j] = 0 ;
}
for ( int j = 1 ; j < cur ; ++ j ) if ( dp[i - 1][j] ) {
for ( int k = 0 ; k < 26 ; ++ k ) {
int t = nxt[j][k] ;
if ( lens[t] <= i ) continue ;
dp[i][t] += dp[i - 1][j] ;
}
}
for ( int j = 1 ; j < cur ; ++ j ) {
ans += dp[i][j] ;
}
}
printf ( "%lld\n" , ans ) ;
}
int main () {
while ( ~scanf ( "%d" , &n ) && n ) solve () ;
return 0 ;
}