[cf700D]Huffman Coding on Segment
令$tot_{i}$为区间$[l,r]$中满足$a_{j}=i$的$j$的个数,将所有非0的$tot_{i}$取出,得到可重集$S$
显然,有以下贪心:不断取出$S$中最小的两个元素,删除这两个元素并加入这两个元素的和,直至$|S|=1$,每一次两个元素的和的和即为答案
使用莫队可以在$o(n\log n)$的时间内得到$S$,但上述过程暴力的复杂度为$o(n\log n)$,无法通过
设置阈值$B$,考虑将上述过程分为两部分——$S$中存在元素$\le B$和$S$中所有元素都$>B$
在第一个部分中,我们可以记录$\le B$的每一个元素的个数,并根据奇偶性简单处理即可(特别的,若恰存在一个元素$\le B$,可以看作所有元素都$>B$),复杂度为$o(B)$
在第二个部分中,显然元素个数不超过$\frac{n}{B}$,直接用上述过程即可,复杂度为$o(\frac{n\log n}{B})$
取$B=\sqrt{n\log n}$即可,总复杂度为$o(n\sqrt{n\log n})$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define ll long long
5 struct Query{
6 int x,y,id;
7 }q[N];
8 multiset<ll>S,S0;
9 int K,B,n,m,a[N],tot[N],sum[N],sum0[N];
10 ll ans[N];
11 bool cmp(Query x,Query y){
12 return (x.x/K<y.x/K)||(x.x/K==y.x/K)&&(x.y<y.y);
13 }
14 void add_times(int x){
15 if (x<=B)sum[x]++;
16 else S.insert(x);
17 }
18 void dec_times(int x){
19 if (x<=B)sum[x]--;
20 else S.erase(S.find(x));
21 }
22 void update_val(int x,int p){
23 dec_times(tot[x]);
24 tot[x]+=p;
25 add_times(tot[x]);
26 }
27 ll calc(){
28 ll ans=0;
29 S0=S;
30 for(int i=1;i<=B;i++)sum0[i]=sum[i];
31 int lst=0;
32 for(int i=1;i<=B;i++){
33 if (!sum[i])continue;
34 if (lst){
35 sum[i]--;
36 add_times(lst+i);
37 ans+=lst+i;
38 lst=0;
39 }
40 ans+=1LL*(sum[i]/2)*(2*i);
41 if (2*i<=B)sum[2*i]+=sum[i]/2;
42 else{
43 for(int j=1;j<=sum[i]/2;j++)S.insert(2*i);
44 }
45 if (sum[i]&1)lst=i;
46 }
47 if (lst)S.insert(lst);
48 while (S.size()>1){
49 int x=(*S.begin());
50 S.erase(S.begin());
51 int y=(*S.begin());
52 S.erase(S.begin());
53 ans+=x+y;
54 S.insert(x+y);
55 }
56 S=S0;
57 for(int i=1;i<=B;i++)sum[i]=sum0[i];
58 return ans;
59 }
60 int main(){
61 scanf("%d",&n);
62 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
63 K=(int)sqrt(n),B=(int)sqrt(n*log2(n));
64 scanf("%d",&m);
65 for(int i=1;i<=m;i++){
66 scanf("%d%d",&q[i].x,&q[i].y);
67 q[i].id=i;
68 }
69 sort(q+1,q+m+1,cmp);
70 int x=1,y=0;
71 for(int i=1;i<=m;i++){
72 while (q[i].x<x)update_val(a[--x],1);
73 while (y<q[i].y)update_val(a[++y],1);
74 while (x<q[i].x)update_val(a[x++],-1);
75 while (q[i].y<y)update_val(a[y--],-1);
76 ans[q[i].id]=calc();
77 }
78 for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
79 }
[cf700D]Huffman Coding on Segment的更多相关文章
- 【CodeForces】700 D. Huffman Coding on Segment 哈夫曼树+莫队+分块
[题目]D. Huffman Coding on Segment [题意]给定n个数字,m次询问区间[l,r]的数字的哈夫曼编码总长.1<=n,m,ai<=10^5. [算法]哈夫曼树+莫 ...
- Codeforces 700D - Huffman Coding on Segment(莫队+根分)
Codeforces 题目传送门 & 洛谷题目传送门 好家伙,刚拿到此题时我连啥是 huffman 编码都不知道 一种对 \(k\) 个字符进行的 huffman 编码的方案可以看作一个由 \ ...
- hdu 1053 (huffman coding, greedy algorithm, std::partition, std::priority_queue ) 分类: hdoj 2015-06-18 19:11 22人阅读 评论(0) 收藏
huffman coding, greedy algorithm. std::priority_queue, std::partition, when i use the three commente ...
- [IR] Huffman Coding
为了保证:Block中,所有的叶子在所有的中间结点的前面.Static: Huffman coding Dynamic: Adaptive Huffman 一些概念 压缩指标 • Compress a ...
- 霍夫曼编码(Huffman Coding)
霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种. 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符 ...
- 哈夫曼编码(Huffman coding)的那些事,(编码技术介绍和程序实现)
前言 哈夫曼编码(Huffman coding)是一种可变长的前缀码.哈夫曼编码使用的算法是David A. Huffman还是在MIT的学生时提出的,并且在1952年发表了名为<A Metho ...
- <Sicily>Huffman coding
一.题目描述 In computer science and information theory, a Huffman code is an optimal prefix code algorith ...
- 哈夫曼编码的理解(Huffman Coding)
哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最 ...
- Huffman coding & Huffman tree
Huffman coding & Huffman tree Huffman coding 哈夫曼编码 / 最优二元前缀码 Huffman tree 哈夫曼树 / 最优二叉树 https://w ...
随机推荐
- 纯净Ubuntu16安装CUDA(9.1)和cuDNN
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Jenkins REST API 实例
背景: Jenkins具有丰富的插件生态,足以满足我们日常工作的需求,但如果我们想通过具体的Jenkins任务直接对外提供服务,而不想将内部的具体实现对外暴露(否则,需添加对应的用户权限,通过页 ...
- 开启Nginx代理HTTPS功能
1.首先查看是否已经安装SSL openssl version -a 2.生成SSL证书 在nginx目录下创建ssl文件夹 cd /etc/pki mkdir nginx cd nginx 生成20 ...
- 题解 [BJOI2017]开车
题目传送门 题目大意 有\(n\)个汽车和\(n\)个加油站,坐标分别为\(a_{1,2,...,n}\)和\(b_{1,2,...,n}\).每辆汽车会到一个加油站,求出最小移动距离之和.有\(m\ ...
- 浏览器有别_HTTP报文的回车换行
本来以为浏览器HTTP报文的生成应该是完全一致的.但最近在做一个项目的时候,发现Safari和Chrome提交同一份表单,后端的处理结果不一致.看提交结果呢,是因为Safari多了个回车.由于原项目的 ...
- 036—环境变量path
day04 课堂笔记 1.开发第一个java程序:HelloWorld 1.1.程序写完以后,一定要ctrl+s进行保存 源代码若修改,需重新进行编译 1.2.编译阶段 怎么编译?使用什么命令?这个命 ...
- DM8数据库单机安装
一.系统概要 表1 部署情况一览表 操作系统 Windows10 数据库版本 DM8(开发版) 数据库类型 单机 磁盘挂载 无 Key信息 无 二.操作系统信息检查 2.1 操作系统版本 [root@ ...
- Java版人脸检测详解上篇:运行环境的Docker镜像(CentOS+JDK+OpenCV)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- HttpClient.PatchAsJsonAsync - dotnet/runtime 项目贡献小记
TL;DR 迫于 PatchAsJsonAsync 方法缺失,我给 dotnet/runtime 项目贡献了相关的 API,可惜要到 .NET7 才能用上. https://github.com/do ...
- TortoiseGit使用
TortoiseGit 前言: 其实作为一名学生,还未接触过企业级开发项目,基本都是一个人在本地敲代码,对于项目管理工具使用的并不多,最常用的命令也就是git clone了,hhh: 前些日子了解了一 ...