首页 > 其他分享 >P2168 [NOI2015] 荷马史诗

P2168 [NOI2015] 荷马史诗

时间:2024-08-10 10:50:14浏览次数:13  
标签:结点 P2168 哈夫曼 荷马史诗 i64 NOI2015 int 字符串 using

题意

给定一个字符串 \(s\) 和整数 \(k\)。

求:1. k 叉哈夫曼树的带权路径之和;2. 求合法的哈夫曼树中,最小的高度是多少。

思路

  1. 按照普通二叉哈夫曼树对其进行编码,将其转化为 \(k\) 叉哈夫曼树。
  2. 编码有可能出现合并到根节点的时候不足 \(k\) 个结点,这会造成结果不优,所以我们可以补入一些长度为 \(0\) 的字符串使得任何一层都是满的。
  3. 通过观察发现每次删除 \(k\) 个结点又补回来 \(1\) 个结点,所以每次减少 \(k - 1\) 个结点,最后剩下一个,所以我们可以一直补长度为 \(0\) 的字符串直到 \(n \equiv 1 (\bmod (k - 1))\)。

代码

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;
using PII = pair<i64, int>;

const int N = 100010;

int n, k;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> k;
    priority_queue<PII, vector<PII>, greater<PII> > q;
    for (int i = 1; i <= n; i++) {
        i64 x;
        cin >> x;
        q.push({x, 0});
    }

    if (k > 2) {
        while (n % (k - 1) != 1) {
            n++;
            q.push({0, 0});
        }
    }

    i64 ans = 0;
    while (q.size() > 1) {
        i64 sum = 0;
        int max_dep = 0;
        for (int i = 1; i <= k; i++) {
            i64 x = q.top().first;
            max_dep = max(max_dep, q.top().second);
            q.pop();
            sum += x;
        }
        q.push({sum, max_dep + 1});
        ans += sum;
    }
    cout << ans << '\n' << q.top().second << '\n';
    return 0;
}

标签:结点,P2168,哈夫曼,荷马史诗,i64,NOI2015,int,字符串,using
From: https://www.cnblogs.com/Yuan-Jiawei/p/18352035

相关文章

  • P2150 [NOI2015] 寿司晚宴
    思路:注意到对于每个数,其\(>19\)的质因数最多只有\(1\)个,称为大质数;对于\(\le19\)的质因数有\(8\)个,称为小质数。设第\(i\)个数的小质数集合为\(h_i\)。那么考虑对于所有数按照大质数从小到大排序,那么对于大质数相同的一段,只能放在两个集合中的一个。考虑状态压缩......
  • 「清新题精讲」P2150 [NOI2015] 寿司晚宴
    P2150[NOI2015]寿司晚宴Statement给定\(n-1\)个数分别为\(2\simn\),从中选出交集为空的两个集合\(A,B\)(集合的并集不必须为\(\{2,\dots,n\}\),且集合可为空)使得不存在\(a\inA,b\inB\)满足\((a,b)\ne1\)(即任意两个数均互质),将方案数对\(p\)取模后输出。\(2\len\le......
  • [Ynoi2015] 纵使日薄西山
    按照题目来模拟,假设\(a_x\)为最大的,那么任意时刻不可能选中\(a_{x-1}\)或者\(a_{x+1}\)来操作的然后就可以发现,我们选出的数一定是不相邻的,也就是说,我们每次在还可以选择的数中找出最大的数(满足此条件下下标最小),并且把相邻的两个数标记为不可选择,一直重复这个过程直到为\(0\);显然......
  • P2178 [NOI2015] 品酒大会 题解(评分:8.0)(2024.2.23)
    前言"I'mfree."做法与题解区都不同,虽然麻烦,但是毕竟复杂度是对的,而且想法很自然,还是写一写吧!Solution题意:给定长为\(n\)的字符串\(s\)和长为\(n\)的数组\(A\),对于每个\(r\),求满足\(\text{LCP}(\text{Suffix}(x),\text{Suffix}(y))\ger,x<y\)的数对\((x,y)\)数......
  • P2168 [NOI2015] 荷马史诗
    原题链接题解1.该题等价于构建一颗k叉树,每个叶子节点都有一个权值\(leaf_i\),树的权值为\(\sum_{1}^{n}leaf_i\),在使树的权值尽可能小的情况下,使最深的叶子节点的深度也尽可能小,即使数的高度尽可能小这个叫做哈夫曼树2.构建过程如下:每次从队列中取出\(k\)个节点,然后把他......
  • 洛谷题单指南-集合-P1955 [NOI2015] 程序自动分析
    原题链接:https://www.luogu.com.cn/problem/P1955题意解读:要判断约数条件是否可以同时满足,主要是要判断不相等的情况。解题思路:对于相等的条件,直接进行集合合并即可;对于不相等的条件,判断两者是否属于同一个集合,如果形成矛盾,则条件不能成立。由于i,j的范围至10^9,定义并查集如果......
  • P3242 [HNOI2015] 接水果 抽象做法
    好吧好吧,自己做出来的第一道整体二分。省流:理解能力比较强的话直接拖到最后看算法流程吧。下面我们称输入时盘子的权值为“盘子的大小”,与文中使用的算法给盘子的赋权区分开。一堆询问第\(k_i\)小,考虑整体二分。先考虑外部过程。上整体二分板子,每次二分\(mid\),形象地把盘......
  • P2178 [NOI2015] 品酒大会
    题意简述定义后缀\(p,q\)是\(r\)相似的当且仅当\(\forall1\lei\ler,s_{p+i-1}=s_{q+i-1}\)。对于每一个\(0\ler<n\),求出:有多少对\(r\)相似的后缀。每个后缀有权值\(a_i\),求在所有\(r\)相似的后缀对\((p,q)\)中\(a_p\cdota_q\)的最大值。若不存在则答案为......
  • TJ -「HNOI2015」开店
    TJ-「HNOI2015」开店(洛谷)一,题意给你一棵\(n\)个节点的树,点有点权,边有边权,\(Q\)次询问每次让你求解点权在\(L\)到\(R\)之间的点到点\(u\)的距离和。(强制在线)数据范围:\(n\le1.5\times10^5,Q\le2\times10^5\)二,思路首先,我们先看弱化版,假设没有年龄的限制,看单个询问,设\(dis_i......
  • [NOI2015] 品酒大会
    独立过了一道NOI的题,开心~我的做法是后缀数组+单调栈+st表,并没有用到并查集点击查看代码#include<bits/stdc++.h>usingnamespacestd;strings;intsa[300005],rk[20][300005],r[300005],n,w,h[300005],p[25],z[300005],st0[20][300005],st1[20][300005],f[600005];lo......