Sort HDU - 5884 哈夫曼权值O(n)
http://acm.hdu.edu.cn/showproblem.php?pid=5884
原来求一次哈夫曼可以有O(n)的做法。
具体是,用两个队列,一个保存原数组,一个保存k个节点合并的数值,然后每次选k个的时候,用two point在两个队列中选k个出来即可。
然后又把新的节点放去第二个队列那里去。
所以,首先需要排序(这样就和求 一次huffman编码的时间复杂度一样了nlogn)
然后这样明显第二个队列是单调递增的。
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = + ;
int a[maxn];
int n, T;
LL que[][maxn], head[], tail[];
LL en = 1e14;
bool check(int val) {
head[] = tail[] = head[] = tail[] = ;
int res = n % (val - );
if (res == ) {
res = val - ;
}
LL ans = ;
if (res == ) {
for (int i = ; i <= n; ++i) que[][tail[]++] = a[i];
} else {
int sum = ;
for (int i = ; i <= res; ++i) sum += a[i];
for (int i = res + ; i <= n; ++i) que[][tail[]++] = a[i];
ans = sum;
que[][tail[]++] = sum;
}
while (true) {
if (ans > T) return false;
LL sum = ;
int want = val;
while (want--) {
LL mi1 = 1e14, mi2 = 1e14;
if (head[] < tail[]) mi1 = que[][head[]];
if (head[] < tail[]) mi2 = que[][head[]];
if (mi1 < mi2) sum += mi1, head[]++;
else sum += mi2, head[]++;
if (mi1 == en && mi2 == en) return true; // 不可以取了
}
que[][tail[]++] = sum;
ans += sum;
}
return true;
}
void work() {
scanf("%d%d", &n, &T);
for (int i = ; i <= n; ++i) scanf("%d", a + i);
sort(a + , a + + n);
int be = , en = n;
// cout << check(2) << endl;
while (be <= en) {
int mid = (be + en) >> ;
if (check(mid)) en = mid - ;
else be = mid + ;
}
printf("%d\n", be);
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
Sort HDU - 5884 哈夫曼权值O(n)的更多相关文章
- 2016 年青岛网络赛---Sort(k叉哈夫曼)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5884 Problem Description Recently, Bob has just learn ...
- HDU 1053 & HDU 2527 哈夫曼编码
http://acm.hdu.edu.cn/showproblem.php?pid=1053 #include <iostream> #include <cstdio> #in ...
- hdu 1565&hdu 1569(网络流--最小点权值覆盖)
方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- hdu 2527哈夫曼树(二叉树的运用)
#include<stdio.h> #include<string.h> #define N 100 #define INF 2000000000 int b[N]; c ...
- HDU 5249:KPI(权值线段树)
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Desc ...
- HDU 1533 KM算法(权值最小的最佳匹配)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- HDU - 5592 ZYB's Premutation (权值线段树)
题意:给出序列前k项中的逆序对数,构造出这个序列. 分析:使用权值线段树来确定序列元素. 逆序对的数量肯定是递增的,从最后一个元素开始逆向统计,则\(a[i] - a[i-1]\)即位置i之前比位置i ...
- hdu 5592 ZYB's Premutation (权值线段树)
最近在线段树的世界里遨游,什么都能用线段树做,这不又一道权值线段树了么. ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others) Mem ...
- Hdu P1394 Minimum Inversion Number | 权值线段树
题目链接 题目翻译: 约定数字序列a1,a2,...,an的反转数是满足i<j和ai>aj的数对(ai,aj)的数量. 对于给定的数字序列a1,a2,...,an,如果我们将第1到m个数字 ...
随机推荐
- POJ 1046 Color Me Less(浅水)
一.Description A color reduction is a mapping from a set of discrete colors to a smaller one. The sol ...
- nginx用cookie控制访问权限实现方法
自己的一个需求需要对a.b.com 下的 /c 这个目录下,cookie d=e 才能访问,如果不是,就重定向到f.html 下面看代码. 代码如下 复制代码 server{ serve ...
- AI设计的若干规则阐述
转自:http://www.gameres.com/491742.html 一般来讲,网络游戏的AI历来就是很简单的AI.相比之下,很多单机游戏的AI就要得复杂一些.而笔者并未从事过大型单机游戏的AI ...
- JS ES6 -- let命令
1.ES6新增了块级作用域的let和const 这新特性let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. for循环的计数器,就很合适使用let命令 ...
- numpy和matlab计算协方差矩阵的不同(matlab是标准的,numpy相当于转置后计算)
matlab是标准的,numpy相当于转置后计算 >> x = [2,0,-1.4;2.2,0.2,-1.5;2.4,0.1,-1;1.9,0,-1.2] x = 2.0000 0 ...
- 伪分布模式 hive查询
[root@node1 ~]# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian ...
- /*带动画效果的hover*/
<!DOCTYPE html> /*带动画效果的hover*/ <html lang="en"> <head> <meta charset ...
- 115个Java面试题和答案
面向对象编程(OOP) Java是一个支持并发.基于类和面向对象的计算机编程语言.下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改. 代码复用. 增强代码的可靠性和灵活性. 增加代码 ...
- 在命令行上启动genymotion虚拟机
自从有了genymotion,多机联调就解放了,一台电脑运行两个genymotion虚拟机毫无压力,不过也看用的是哪种os image,之前我以为google自己的Nexus应该最适应,哪知道开起来比 ...
- StringBuffer输出
public class Test { public static void main(String[] args) { StringBuffer a = new StringBuffer(" ...