思路:我们可以发现两个字符串的最长公共前缀就是字典树中的最近公共祖先。然而这道题,比如说某个结点是x个字符串的前缀,那么当前结点对答案的贡献为x * (x - 1) / 2,就是x中任选两个字符串组合,因为在这之前,这些字符串的前缀在计算其他结点的时候已经被算过了。
代码:
#define ll long long
#define N 300010
using namespace std;
ll n,ch[N][26],sz[N];
int main(){
ll i,x,tot=1;
cin>>n;
while(n--)
{
string s;
cin>>s;
for(i=0,x=1;i<s.size();i++)
{
sz[x]++;
if(!ch[x][s[i]-'a'])
{
ch[x][s[i]-'a']=++tot;
}
x=ch[x][s[i]-'a'];
}
sz[x]++;
}
ll ans=0;
for(i=2;i<=tot;i++)
{
ans+=sz[i]*(sz[i]-1)/2;
}
cout<<ans<<'\n';
return 0;
}