令$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的更多相关文章

  1. 【CodeForces】700 D. Huffman Coding on Segment 哈夫曼树+莫队+分块

    [题目]D. Huffman Coding on Segment [题意]给定n个数字,m次询问区间[l,r]的数字的哈夫曼编码总长.1<=n,m,ai<=10^5. [算法]哈夫曼树+莫 ...

  2. Codeforces 700D - Huffman Coding on Segment(莫队+根分)

    Codeforces 题目传送门 & 洛谷题目传送门 好家伙,刚拿到此题时我连啥是 huffman 编码都不知道 一种对 \(k\) 个字符进行的 huffman 编码的方案可以看作一个由 \ ...

  3. 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 ...

  4. [IR] Huffman Coding

    为了保证:Block中,所有的叶子在所有的中间结点的前面.Static: Huffman coding Dynamic: Adaptive Huffman 一些概念 压缩指标 • Compress a ...

  5. 霍夫曼编码(Huffman Coding)

    霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种. 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符 ...

  6. 哈夫曼编码(Huffman coding)的那些事,(编码技术介绍和程序实现)

    前言 哈夫曼编码(Huffman coding)是一种可变长的前缀码.哈夫曼编码使用的算法是David A. Huffman还是在MIT的学生时提出的,并且在1952年发表了名为<A Metho ...

  7. <Sicily>Huffman coding

    一.题目描述 In computer science and information theory, a Huffman code is an optimal prefix code algorith ...

  8. 哈夫曼编码的理解(Huffman Coding)

    哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最 ...

  9. Huffman coding & Huffman tree

    Huffman coding & Huffman tree Huffman coding 哈夫曼编码 / 最优二元前缀码 Huffman tree 哈夫曼树 / 最优二叉树 https://w ...

随机推荐

  1. vite首次启动加载慢

    背景 随着vue3的到来,vite开始被各大vue3组件库使用,公司开始一个新项目,准备尝试用vite试一波. 问题发现 当把公司新项目移植到vite后,启动非常快,但发现页渲染时间慢了很多 可以看到 ...

  2. CEF使用过程问题合集

    CEF使用过程问题合集 1.Couldn't mmap icu data file 解决方案:检查程序执行目录下是否有icudtl.dat文件,如果没有请从cef的Resources文件夹中复制一份. ...

  3. Azure Devops实践(5)- 构建springboot项目打包docker镜像及容器化部署

    使用Azure Devops构建java springboot项目,创建镜像并容器化部署 1.创建一个springboot项目,我用现有的项目 目录结构如下,使用provider项目 在根目录下添加D ...

  4. Centos7最小安装后快速初始化脚本

    功能说明 服务器通常使用最小化安装操作系统,使用该脚本可快速初始化一些基本配置,包括以下: 1.ssh修改默认端口 2.ssh禁止root登陆 3.selinux及firewalld禁用 4.hist ...

  5. python中列表和元组的区别

    列表(list)特点: 1.可变类型且有序的,有索引值. 元组特点: 1.不可变类型且有序的,通过下标索引值访问 2.元组里面只有一个元素的时候该元组类型就是这个元素的类型.例如:t=(1) t的类型 ...

  6. 模拟赛T2 交换 解题报告

    模拟赛T2 交换 解题报告 题目大意: 给定一个序列和若干个区间,每次从区间中选择两个数修改使字典序最小. \(n,m\) 同阶 \(10^6\) 2.1 算法 1 按照题意模拟,枚举交换位置并比较. ...

  7. 【UE4 设计模式】观察者模式 Observer Pattern

    概述 描述 定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新.观察者模式又叫做 发布-订阅(Publish/Subscribe)模式 模型-视图(M ...

  8. BUAA软件工程结对项目作业

    BUAA软件工程结对项目 小组成员:16005001,17373192 1.教学班级和项目地址 项目 内容 这个作业属于哪个课程 博客园班级连接 这个作业的要求在哪里 结对项目作业 我在这个课程的目标 ...

  9. oo第四次博客-UML暨学期总结

    一. 本单元两次作业架构设计 这两次作业实际上难度不大,不存在算法上的难题,大部分时间都是用在处理UML图中各个元素的关系上. 第一次UML主要处理UML类图.有UMLclass,UMLinterfa ...

  10. IDEA + maven 零基础构建 java agent 项目

    200316-IDEA + maven 零基础构建 java agent 项目 Java Agent(java 探针)虽说在 jdk1.5 之后就有了,但是对于绝大多数的业务开发 javaer 来说, ...