题目大意:

  给出总长度不超过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. Linux上vim编辑器缩进的设置(方便如书写python代码)

    因为刚刚安装了Ubuntu虚拟机,知乎大神推荐用VIM编辑器,然后发现在Python缩进上不方便,查了点资料,整理出来,以便自己以后忘了还可以再看看. 第一步: 打开终端,在终端上输入 vim ~/. ...

  2. Luogu1081 NOIP2012 开车旅行 倍增

    题目传送门 为什么NOIP的题目都这么长qwq 话说2012的D1T3和D2T3都是大火题啊qwq 预处理神题 对于这种跳跳跳的题目考虑使用倍增优化枚举.先预处理某个点之后距离最小和次小的城市,然后倍 ...

  3. jQuery checkbox全选 和全部取消

    1.chkAll选中,全部chk选中  ,chkAll取消选中,全部chk取消选中 //chkAll选中,全部chk选中 ,chkAll取消选中,全部chk取消选中 $("#chkAll&q ...

  4. Luogu P1546 最短网络 Agri-Net

    其实这道题根本没必要写,但为了测试vector+堆优化的Prim试一发. 再次觉得Prim和Dijkstra很像,堆优化版本也差不多. 和Dijkstra一样,Prim也是在之前的dis点中选取一个最 ...

  5. BJOI2019 题解

    BJOI2019 题解 在更了在更了 P5319 [BJOI2019]奥术神杖 对\(V_i\)求个\(\ln\)变成了让平均数最大,显然套分数规划,然后ac自动机上面dp #include<b ...

  6. 扩展ASP.NET Identity使用Int做主键

    当我们默认新建一个ASP.NET MVC项目的时候,使用的身份认证系统是ASP.NET Identity.但是这里的Identity使用的主键为String类型的GUID.当然这是大多数系统首先类型. ...

  7. webpack教程(一)——初体验

    首先全局安装webpack,再npm初始化一个项目,并局部安装webpack开发工具 $ npm install webpack -g npm init (项目名称) $ npm install we ...

  8. SSO单点登录_理解

    SSO核心意义就一句话:一处登录,处处登录:一处注销,处处注销.即:在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 很多人容易把SSO与OAuth搞混.这里简单说明一下: OA ...

  9. 如何新增一个ssh-key文件

    前言 由于在公司有一个sshkey 在用,用于绑定公司的git code 仓库.那么在家要连上git hub 仓库,就也需要一个 ssh key .为了避免公司信息外露,所以还是新增一个ssh key ...

  10. 软件工程附加篇章:进阶四则运算和Core对接

    0x01 :计算模块(Core)和前端对接 首先特别结对编程刘乾组(SivilTaram)提供的计算模块(Core),http://www.cnblogs.com/SivilTaram/p/48599 ...