Discription

Arkady's code contains nn 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 aa is a prefix of a string bb if you can delete some (possibly none) characters from the end of bb and obtain aa.

Please find this minimum possible total length of new names.

Input

The first line contains a single integer nn (1≤n≤1051≤n≤105) — the number of variables.

The next nn 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 105105. 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", "co", "c".

In the second example we can shorten the last name to "aac" and the first name to "a" without changing the other names.

很显然是可以在trie树上贪心的。

每个点x开一个map,存单词结尾在x子树内的点的深度集合。

如果点x没有被单词结尾覆盖,那么就把最深的放到这里。

向上合并的时候启发式合并就好啦。。。。

复杂度 O(N * log ^ 2(N))

#include<bits/stdc++.h>
#include <typeinfo>
#define ll long long
using namespace std;
const int maxn=100005; map<int,int> mmp[maxn];
map<int,int> :: iterator it;
int ch[maxn][26],cnt,n,N,ans,dep[maxn],word[maxn];
char S[maxn]; inline void ins(){
int now=0,c,depth=0;
for(int i=0;i<N;i++){
c=S[i]-'a';
if(!ch[now][c]) ch[now][c]=++cnt;
now=ch[now][c],dep[now]=++depth;
} word[now]++;
} void dfs(int x){
for(int i=0,to;i<26;i++) if(ch[x][i]){
to=ch[x][i],dfs(to); if(mmp[to].size()>mmp[x].size()) swap(mmp[to],mmp[x]); for(it=mmp[to].begin();it!=mmp[to].end();++it) mmp[x][it->first]+=it->second; mmp[to].clear();
} if(word[x]) mmp[x][dep[x]]+=word[x];
else if(x){
it=--mmp[x].lower_bound(1e9); ans-=(it->first)-dep[x]; if(!(--(it->second))) mmp[x].erase(it); mmp[x][dep[x]]++;
}
} int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
fill(S,S+N,0);
scanf("%s",S),N=strlen(S),ans+=N;
ins();
} dfs(0); printf("%d\n",ans);
return 0;
}

  

CodeForces - 965E Short Code的更多相关文章

  1. Codeforces 965E Short Code 启发式合并 (看题解)

    Short Code 我的想法是建出字典树, 然后让后面节点最多的点优先向上移到不能移为止, 然后gg. 正确做法是对于当前的节点如果没有被占, 那么从它的子树中选出一个深度最大的点换到当前位置. 用 ...

  2. codeforces 965E Trie+multiset

    E. Short Code time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  3. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  4. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] E】Short Code

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先建立一棵字典树. 显然,某一些节点上会被打上标记. 问题就转化成求所有标记的深度的和的最小值了. (标记可以上移,但是不能在同一位 ...

  5. Codeforces 543A Writing Code

    http://codeforces.com/problemset/problem/543/A 题目大意:n个人,一共要写m行程序,每个程序员每行出现的bug数为ai,要求整个程序出现的bug数不超过b ...

  6. CodeForces 543A - Writing Code DP 完全背包

    有n个程序,这n个程序运作产生m行代码,但是每个程序产生的BUG总和不能超过b, 给出每个程序产生的代码,每行会产生ai个BUG,问在总BUG不超过b的情况下, 我们有几种选择方法思路:看懂了题意之后 ...

  7. Codeforces 768B B. Code For 1

    参考自:https://www.cnblogs.com/ECJTUACM-873284962/p/6423483.html B. Code For 1 time limit per test:2 se ...

  8. 【codeforces 768B】Code For 1

    [题目链接]:http://codeforces.com/contest/768/problem/B [题意] 一开始给你一个数字n; 让你用这个数字n根据一定的规则生成序列; (如果新生成的序列里面 ...

  9. 【codeforces 765B】Code obfuscation

    [题目链接]:http://codeforces.com/contest/765/problem/B [题意] 让你把每个变量都依次替换成a,b,c,-.d这些字母; 且要按顺序先用a再用b-.c.d ...

随机推荐

  1. 【BZOJ4325】NOIP2015 斗地主 搜索+贪心

    这个东西考试的时候一眼以为状压就压炸了考试又了一下午.....最后我打出来发现后几个点10min都过不去,我大概算了一下,可能是吧.......最后一脸懵逼的我去怂了正解,我们发现只要确定了顺子就可以 ...

  2. ext radiogroup如何取值和设值

    var radios = Ext.create('Ext.form.Panel', { title: 'RadioGroup Example', width: 300, height: 125, bo ...

  3. 从零开始学习MXnet(四)计算图和粗细粒度以及自动求导

    这篇其实跟使用MXnet的关系不大,但对于我们理解深度学习的框架设计还是很有帮助的. 首先还是对promgramming models的一个简单介绍,这个东西实际上是在编译里面经常出现的东西,我们在编 ...

  4. Planning your upgrade with Upgrade Advisor

    Planning your upgrade with Upgrade Advisor You should use the Upgrade Advisor tool (if it is availab ...

  5. css属性选择器应用

    代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. ...

  6. 【MySQL优化】使用show status查看MySQL服务器状态信息

    在网站开发过程中,有些时候我们需要了解MySQL的服务器状态信息,譬如当前MySQL启动后的运行时间,当前MySQL的客户端会话连接数,当前MySQL服务器执行的慢查询数,当前MySQL执行了多少SE ...

  7. python3,循环,方法练习2

    1:编写for循环,利用索引遍历出每一个字符 msg = 'hello egon 666' msg = 'hello egon 666' i = 0 for i in range(0, len(msg ...

  8. HDU1281(二分图最大匹配,棋盘建图,找关键点)

    棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. java小工具——timer

    定时器Timer 用途:做定时器用的. public static void main(String[] args) { Timer timer = new Timer(); timer.schedu ...

  10. eclipse断点调试时不能进入断点调试

    页面JavaScript代码有错误!!!F12调试.