time limit per test : 1 second
memory limit per test : 256 megabytes
Arkady’s code contains nnn variables. Each variable has a unique name consisting of lowercase English letters only. One day Arkady decided to shorten his code.
He wants to replace each variable name with its non-empty prefix so that these new names are still unique (however, a new name of some variable can coincide with some old name of another or same variable). Among such possibilities he wants to find the way with the smallest possible total length of the new names.
A string aaa is a prefix of a string b if you can delete some (possibly none) characters from the end of bbb and obtain aaa .Please find this minimum possible total length of new names.
Input
The first line contains a single integer n(1≤n≤105)n(1≤n≤10^5)n(1≤n≤105) — the number of variables.
The next nnn lines contain variable names, one per line. Each name is non-empty and contains only lowercase English letters. The total length of these strings is not greater than 10510^5105. The variable names are distinct.
Output
Print a single integer — the minimum possible total length of new variable names.
Examples
Input
3
codeforces
codehorses
code
Output
6
Input
5
abba
abb
ab
aa
aacada
Output
11
Input
3
telegram
digital
resistance
Output
3
Note
In the first example one of the best options is to shorten the names in the given order as "cod""cod""cod", "co""co""co", "c""c""c".
In the second example we can shorten the last name to "aac""aac""aac" and the first name to "a""a""a" without changing the other names.
题意:
给定nnn个互不相同的字符串,你可以把一个字符串变成他的一个非空前缀,问:使得这些字符串仍然互不相同的最小字符串总长度是多少。
题解:
你先建一个trie,每个节点放一个multiset,表示前缀为当前节点的字符串们的长度集合。但是预处理的时候只需要放在每个字符串的结束节点就行了,反正后面合并的时候都能求。
那么我们从root开始dfs。首先,如果当前节点不是root并且当前节点不是某个字符串的结尾节点,那么以当前节点为前缀的字符串中可以有一个可以截断成当前节点所代表的长度。将所有的儿子节点的信息存入当前节点,然后取一个最长的截断即可。记得用启发式合并。
#include<bits/stdc++.h>
#define LiangJiaJun main
using namespace std;
int ch[100004][34],sz;
int n,m;
char s[100004];
multiset<int>lv[100004];
void INS(char *s){
int l=strlen(s+1);
int u=0;
for(int i=1;i<=l;i++){
int to=s[i]-'a';
if(!ch[u][to]){
lv[sz].clear();
ch[u][to]=sz++;
}
u=ch[u][to];
}
lv[u].insert(l);
}
void dfs(int x,int dep){
bool ok=(x&&lv[x].size()==0);
for(int i=0;i<26;i++){
int to=ch[x][i];
if(!to)continue;
dfs(to,dep+1);
if(lv[x].size()<lv[to].size())swap(lv[x],lv[to]);
for(int v:lv[to])lv[x].insert(v);
lv[to].clear();
}
if(ok){
lv[x].erase(--lv[x].end());
lv[x].insert(dep);
}
}
int LiangJiaJun(){
scanf("%d",&n);
sz=1;
memset(ch[0],0,sizeof(ch[0]));
for(int i=1;i<=n;i++){
scanf("%s",s+1);
INS(s);
}
dfs(0,0);
int ans=0;
for(int v:lv[0])ans+=v;
printf("%d\n",ans);
return 0;
}