Description
在一個奇怪的村子中,很多人的名字都很長,比如aaaaa, bbb and abababab。 名字這麼長,叫全名顯然起來很不方便。所以村民之間一般只叫名字的前綴。比如叫'aaaaa'的時候可以只叫'aaa',因爲沒有第二個人名字的前三個字母是'aaa'。不過你不能叫'a',因爲有兩個人的名字都以'a'開頭。村裏的人都很聰明,他們總是用最短的稱呼叫人。輸入保證村裏不會有一個人的名字是另外一個人名字的前綴(作爲推論,任意兩個人的名字都不會相同)。 如果村裏的某個人要叫所有人的名字(包括他自己),他一共會說多少個字母?
Input
輸入第一行爲數據組數T (T<=10)。每組數據第一行爲一個整數n(1<=n<=1000),即村裏的人數。以下n行每行爲一個人的名字(僅有小寫字母組成)。輸入保證一個村裏所有人名字的長度之和不超過1,000,000。
Output
對於每組數據,輸出所有人名字的字母總數。
1 3 aaaaa bbb abababab
5
字典樹記錄半個模版
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5+10;
int name[N][26];
int sz;
int n;
int ans;
char s[100000];
int val[N*10]; ///開到足夠大
void inssert()
{
int u = 0;
int len = strlen(s);
for(int i = 0;i < len;i++){
int c = s[i]-'a';
if(!name[u][c]){
memset(name[sz],0,sizeof name[sz]);
name[u][c] = sz++;
}
val[u]++;
u = name[u][c];
}
val[u]++;
}
void dfs(int u,int dep)
{
for(int i = 0;i < 26;i++){
if(name[u][i]){
int t = name[u][i];
if(val[t] == 1){
ans += dep;
continue;
}
dfs(name[u][i],dep+1);
}
}
}
int main(void)
{
int T;
scanf("%d",&T);
while(T--){
sz = 1; ///置1
ans = 0;
memset(name[0],0,sizeof name[0]);
memset(val,0,sizeof val);
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%s",s);
inssert();
}
dfs(0,1);
printf("%d\n",ans);
}
return 0;
}