CodeForces - 965E Short Code
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
3
codeforces
codehorses
code
6
5
abba
abb
ab
aa
aacada
11
3
telegram
digital
resistance
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的更多相关文章
- Codeforces 965E Short Code 启发式合并 (看题解)
Short Code 我的想法是建出字典树, 然后让后面节点最多的点优先向上移到不能移为止, 然后gg. 正确做法是对于当前的节点如果没有被占, 那么从它的子树中选出一个深度最大的点换到当前位置. 用 ...
- codeforces 965E Trie+multiset
E. Short Code time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)
[Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...
- 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] E】Short Code
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先建立一棵字典树. 显然,某一些节点上会被打上标记. 问题就转化成求所有标记的深度的和的最小值了. (标记可以上移,但是不能在同一位 ...
- Codeforces 543A Writing Code
http://codeforces.com/problemset/problem/543/A 题目大意:n个人,一共要写m行程序,每个程序员每行出现的bug数为ai,要求整个程序出现的bug数不超过b ...
- CodeForces 543A - Writing Code DP 完全背包
有n个程序,这n个程序运作产生m行代码,但是每个程序产生的BUG总和不能超过b, 给出每个程序产生的代码,每行会产生ai个BUG,问在总BUG不超过b的情况下, 我们有几种选择方法思路:看懂了题意之后 ...
- 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 ...
- 【codeforces 768B】Code For 1
[题目链接]:http://codeforces.com/contest/768/problem/B [题意] 一开始给你一个数字n; 让你用这个数字n根据一定的规则生成序列; (如果新生成的序列里面 ...
- 【codeforces 765B】Code obfuscation
[题目链接]:http://codeforces.com/contest/765/problem/B [题意] 让你把每个变量都依次替换成a,b,c,-.d这些字母; 且要按顺序先用a再用b-.c.d ...
随机推荐
- 用JSR的@Inject代替@Autowired完成自动装配
从spring3.0开始spring支持JSR-330 的标准注解.主要是javax.inject这个包下的: 下面的例子用@Inject代替@Autowired.完成自动装配: MovieFinde ...
- Spring学习--切面优先级及重用切点表达式
指定切面的优先级: 在同一个链接点上应用不止一个切面时 , 除非明确指定 , 否则它们的优先级是不确定的. 切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定. 实现 Ord ...
- npm install 报node-sass错误
Node Sass could not -bit with Node.js .x Found bindings for the following environments: - OS X -bit ...
- Linux 下面adb命令的使用
平板或者android手机使用adb是非常方便的.接下来我就介绍下adb使用以及一些常用的命令. 1,连接 用adb连接线,一端接PC的USB中,一端接平板或手机的adb口,当然得确保线没有问题,而且 ...
- python3 生成器表达式
生成器表达式 [i for i in range(100)] #列表解析 与列表解析的不同是,列表解析用中括号,生成器表达式用小括号 g = (i for i in range(1000)) #生成器 ...
- 常见协议基础知识总结--DHCP协议
DHCP动态主机配置协议,简单点说,就是提供了自动获取ip地址的功能,基于四层的UDP协议: 以下描述此协议的整个工作流程: (1) 客户端发送discovery报文,二三层广播报文,源ip地址全0: ...
- [ 总结 ] Linux下两种常用的双网卡绑定
1. mode=0 (round-robin) 链路聚合:将两个或者更多数据信道结合成一个单一的信道,该信道以一个更高带宽的逻辑链路出现,链路聚合一般用来连接一个或多个带宽需求量大的设备,链路聚合是指 ...
- Android的简单应用(三)——为你的程序添加监听器
平时在写程序时经常会遇到监听器,比如按钮的click监听器,按键监听器等等.而android中的监听器和java中的回调函数是同一个概念,都是在底层代码中定义一个接口来调用高层的代码.那么什么是回调函 ...
- 【SQL】持久性存储模块PSM
1. 创建PSM函数和过程 创建过程: CREATE PROCEDURE 名字 (参数) 局部声明: 过程体: 创建函数: CREATE FUNCTION 名字 (参数) RETURNS 类型 局部声 ...
- python模拟鼠标和键盘操作
import win32api import win32con import win32gui from ctypes import * import time VK_CODE = { 'backsp ...