题目大意:

  给出总长度不超过1E+5的不重复字符串集,给每个字符串选一个前缀使得可以区分它。

题目分析:

  KAN出的DIV2难度一般不高,想升Ranting的可以试试。

  简单的树上启发式合并,建出Trie树,一开始每个字符串用自己表示,每次向上合并的时候选出堆中最大元素变成当前位置,特判一下有end的地方即可。

  证明也很简单,我们考虑一个根没被选的子树,若我们要使得这个子树的代价最小,那么我们一定要选择一个位置放到根上来,不难发现选择深度最大的点是会最小的。由于树的子结构的关系,这样向上归纳也是正确的。

代码:

  

 #include<bits/stdc++.h>
using namespace std; const int sigma = ; int n,num,len,root;
char str[];
struct trie{
int end,sz,nxt[];
}T[]; int Num(char ch){return ch-'a';} void insert(int now,int pla){
if(pla == len) {T[now].sz++;T[now].end=;return;}
int um = Num(str[pla]);
if(T[now].nxt[um]){
insert(T[now].nxt[um],pla+);
}else{
num++; T[now].nxt[um] = num;
insert(T[now].nxt[um],pla+);
}
} void dfs(int now){
for(int i=;i<sigma;i++)
if(T[now].nxt[i]) dfs(T[now].nxt[i]),T[now].sz+=T[T[now].nxt[i]].sz;
} void read(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%s",str);
len = strlen(str);
insert(root,);
}
dfs(root);
} int ans = ;
int bel[];
priority_queue<int,vector<int>,less<int> > q[]; int merge(int a,int b){
if(q[a].size()<q[b].size()){
while(!q[a].empty()){
int k = q[a].top();q[a].pop();
q[b].push(k);
}
return b;
}else{
while(!q[b].empty()){
int k = q[b].top();q[b].pop();
q[a].push(k);
}
return a;
}
} void dfs2(int now,int val){
int flag = false;
for(int i=;i<sigma;i++){
if(T[now].nxt[i]) flag=true,dfs2(T[now].nxt[i],val+);
}
if(!flag){bel[now]=++num;q[num].push(val);return;}
for(int i=;i<sigma;i++){
if(T[now].nxt[i]){
if(bel[now]){bel[now]=merge(bel[now],bel[T[now].nxt[i]]);}
else bel[now] = bel[T[now].nxt[i]];
}
}
if(T[now].end){
q[bel[now]].push(val);
}else{
q[bel[now]].pop();
q[bel[now]].push(val);
}
} void work(){
num = ;
for(int i=;i<sigma;i++){
if(!T[root].nxt[i]) continue;
dfs2(T[root].nxt[i],);
int hh = bel[T[root].nxt[i]];
while(!q[hh].empty()){
ans += q[hh].top();q[hh].pop();
}
}
printf("%d",ans);
} int main(){
read();
work();
return ;
}

Codeforces965E Short Code 【启发式合并】【堆】的更多相关文章

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

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

  2. BZOJ4919:[Lydsy1706月赛]大根堆(set启发式合并)

    Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质: ...

  3. UOJ356 [JOI2017春季合宿] Port Facility 【启发式合并】【堆】【并查集】

    题目分析: 好像跑得很快,似乎我是第一个启发式合并的. 把玩具看成区间.首先很显然如果有两个玩具的进出时间有$l1<l2<r1<r2$的关系,那么这两个玩具一定在不同的栈中间. 现在 ...

  4. P5290 [十二省联考2019]春节十二响(堆+启发式合并)

    P5290 [十二省联考2019]春节十二响 从特殊到一般 我们先看链的情况. 我们把点$1$左右的两条子链分别扔入堆里 每次取出两个堆的最大值,把答案累加上更大的那个(另一堆为空则直接加上去). 那 ...

  5. bzoj 4919 [Lydsy1706月赛]大根堆 set启发式合并+LIS

    4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 599  Solved: 260[Submit][Stat ...

  6. CF827D Best Edge Weight[最小生成树+树剖/LCT/(可并堆/set启发式合并+倍增)]

    题意:一张图求每条边边权最多改成多少可以让所有MST都包含这条边. 这题还是要考察Kruskal的贪心过程. 先跑一棵MST出来.然后考虑每条边. 如果他是非树边,要让他Kruskal的时候被选入,必 ...

  7. BZOJ4919 [Lydsy1706月赛]大根堆 【dp + 启发式合并】

    题目链接 BZOJ4919 题解 链上的\(LIS\)维护一个数组\(f[i]\)表示长度为\(i\)的\(LIS\)最小的结尾大小 我们可以用\(multiset\)来维护这个数组,子树互不影响,启 ...

  8. BZOJ.4919.[Lydsy1706月赛]大根堆(线段树合并/启发式合并)

    题目链接 考虑树退化为链的情况,就是求一个最长(严格)上升子序列. 对于树,不同子树间是互不影响的.仿照序列上的LIS,对每个点x维护一个状态集合,即合并其子节点后的集合,然后用val[x]替换掉第一 ...

  9. BZOJ4919 大根堆(动态规划+treap+启发式合并)

    一个显然的dp是设f[i][j]为i子树内权值<=j时的答案,则f[i][j]=Σf[son][j],f[i][a[i]]++,f[i][a[i]+1~n]对其取max.这样是可以线段树合并的, ...

随机推荐

  1. 可以设置超时版的的fetch

    // 超时版的fetch _fetch(fetch, timeout) { return Promise.race([ fetch, new Promise(function (resolve, re ...

  2. 前后端交互json字符串

    //将需要的参数转成json字符串,然后用utf-8编码 var obj = encodeURIComponent(JSON.stringify(this.categories),"utf- ...

  3. 5、数组&字符串&结构体&共用体&枚举

    程序中内存从哪里来 三种内存来源:栈(stack).堆(heap).数据区(.date): 栈(stack) 运行自动分配.自动回收,不需要程序员手工干预: 栈内存可以反复使用: 栈反复使用后,程序不 ...

  4. 【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--路由限制及选择篇(2/8)【route】

    文章目录 前情概要 上文中的RouteHandler中有一个重要方法GetActionDescriptor没有贴代码和说,接下来我们就说一说这个方法. 使用controllerName.actionN ...

  5. React.js 入门与实战课程思维导图

    原文发表于我的技术博客 我在慕课网的「React.js 入门与实战之开发适配PC端及移动端新闻头条平台」课程已经上线了,在这里分享了课程中的思维导图,供大家参考. 原文发表于我的技术博客 此导图为课程 ...

  6. MongoDB日常运维操作命令小结

    总所周知,MongoDB是一个NoSQL非数据库系统,即一个数据库可以包含多个集合(Collection),每个集合对应于关系数据库中的表:而每个集合中可以存储一组由列标识的记录,列是可以自由定义的, ...

  7. Centos下SVN环境部署记录

    大多数情况下,我们日常工作中用的版本控制系统都会选择分布式的Git,它相比于集中式的SVN有很多优势.但是有些项目软件基于自身限制,可能只支持SVN做工程同步.废话就不多说了,下面记录下SVN的部署和 ...

  8. windows如何查看电脑开关机记录

    如何查看电脑开关机记录 (一)如果你只是想查看一下,从昨天关机到今天开机之间有没有人使用我的计算机,在“开始”菜单的运行”中输入“eventvwr.msc”,或者是按下"开始菜单" ...

  9. openpyxl 实现excel字母列号与数字列号之间的转换

    https://www.cnblogs.com/apple2016/p/9686433.html

  10. 树莓派 Raspberry Pi 更换国内源

    http://www.shumeipaiba.com/wanpai/jiaocheng/16.html