luogu 3466 对顶堆
显然答案是将一段区间全部转化成了其中位数
这样的话,需要维护一个数据结构支持查询当前所有数中位数
对顶堆
用两个堆
将 < 中位数的数放入大根堆
将 > 中位数的数放入小根堆
这样就会存在删除操作
删除的时候
由于无法快速删除
只需做个标记,标记该数被删除了一次
并且堆的实际大小也应该另外记录维护
在标记时需要更改相应的堆的大小与权值
答案就非常显然了
#include <bits/stdc++.h> using namespace std; #define gc getchar()
inline int read() {
int x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x;
} #define Rep(i, a, b) for(int i = a; i <= b; i ++)
#define Fin(str) freopen(str, "r", stdin)
#define Fout(str) freopen(str, "w", stdout)
#define E return
#define LL long long const int N = 1e5 + ; int n, k;
int A[N], use[N * ]; priority_queue <int, vector<int>, less<int> > Big;
priority_queue <int, vector<int>, greater<int> > Small; int Size1, Size2;
LL Sum1, Sum2; void Update() {
while(Big.size() && use[Big.top()]) use[Big.top()] --, Big.pop();
while(Small.size() && use[Small.top()]) use[Small.top()] --, Small.pop();
} void Out(); void Add(int x) {
Update();
while(Size1 < (k + ) / && Small.size()) {
int num = Small.top();
Small.pop();
Size1 ++, Sum1 += num;
Size2 --, Sum2 -= num;
Big.push(num);
Update();
}
Update();
if(Size1 < (k + ) / ) {
Size1 ++, Sum1 += x, Big.push(x); return ;
}
Update();
int num = Big.top();
if(x < num) {
Small.push(num);
Big.pop();
Size2 ++, Sum2 += num;
Sum1 += (x - num);
Big.push(x);
} else {
Size2 ++, Sum2 += x, Small.push(x);
}
Update();
} void Del(int x) {
use[x] ++;
int top1 = Big.top();
if(x <= top1) Size1 --, Sum1 -= x;
else Size2 --, Sum2 -= x;
} LL Calc() {
Update();
LL mid = Big.top();
return 1ll * mid * Size1 - 1ll * Sum1 + 1ll * Sum2 - 1ll * mid * Size2;
} int main() {
n = read(), k = read();
Rep(i, , n) A[i] = read();
Rep(i, , k) Add(A[i]);
LL Answer = Calc();
int bef = ;
int flag = k, mid = Big.top();
Rep(i, k + , n) {
Del(A[++ bef]);
Add(A[i]);
LL Ans = Calc();
if(Ans < Answer) {
flag = i, mid = Big.top();
Answer = Ans;
}
}
cout << Answer << "\n";
Rep(i, , n) {
if(i <= flag && i >= flag - k + ) {
cout << mid << "\n";
} else cout << A[i] << "\n";
}
return ;
}
luogu 3466 对顶堆的更多相关文章
- 【Luogu P1168】【Luogu P1801&UVA 501】中位数&黑匣子(Black Box)——对顶堆相关
Luogu P1168 Luogu P1801 UVA 501(洛谷Remote Judge) 前置知识:堆.优先队列STL的使用 对顶堆 是一种在线维护第\(k\)小的算法. 其实就是开两个堆,一个 ...
- Luogu 3466 [POI2008]KLO-Building blocks
BZOJ 1112. 题意相当于在一个长度为$k$的区间内选择一个数$s$使$\sum_{i = 1}^{k}\left | a_i - s \right |$最小. 很显然是中位数. 然后只要写一个 ...
- hdu3282 链表或者对顶堆
维护序列的动态中位数 第一次用链表做题..感觉指针指来指去也挺麻烦的.. 本题链表解法就是用数组模拟出一个链表,然后离线输入所有数,排序,按照输入顺序在链表里删除元素,一次性删掉两个,然后中位数指针对 ...
- 【uoj#280】[UTR #2]题目难度提升 对顶堆+STL-set
题目描述 给出 $n$ 个数 $a_1,a_2,...,a_n$ ,将其排为序列 $\{p_i\}$ ,满足 $\{前\ i\ 个数的中位数\}$ 单调不降.求字典序最大的 $\{p_i\}$ . 其 ...
- hdu4261 Estimation[暴力dp+对顶堆]
https://vjudge.net/problem/HDU-4261 对于一个长2000的数列划分最多25个块,每块代价为块内每个数与块内中位数差的绝对值之和,求最小总代价. 套路化地,设$f[i] ...
- 【POJ 3784】 Running Median (对顶堆)
Running Median Description For this problem, you will write a program that reads in a sequence of 32 ...
- P1168 中位数(对顶堆)
题意:维护一个序列,两种操作 1.插入一个数 2.输出中位数(若长度为偶数,输出中间两个较小的那个) 对顶堆 维护一个小根堆,一个大根堆,大根堆存1--mid,小根堆存mid+1---n 这样堆顶必有 ...
- poj3784 Running Median[对顶堆]
由于我不会讲对顶堆,所以这里直接传上一个巨佬的学习笔记. 对顶堆其实还是很容易理解的,想这题的时候自己猜做法也能把没学过的对顶堆给想出来.后来了解,对顶堆主要还是动态的在线维护集合$K$大值.当然也可 ...
- 洛谷 - P1801 - 黑匣子 - 对顶堆
这道题是提高+省选-的难度,做出来的话对数据结构题目的理解会增加很多. 可以使用一种叫做对顶堆的东西,对顶堆是在线维护第n小的logn的算法.大概的思路是,假如我们要找的是第n小,我们就维护一个大小为 ...
随机推荐
- Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE
删除logs文件夹日志即可
- java 堆 排序学习
/** * <html> * <body> * <P> Copyright 1994 JsonInternational</p> * <p> ...
- ADO.Net和SqlHelper封装
1.什么是ADO.Net 简单来讲,ADO.NET是用于和数据源打交道的.Net结束,是一组向.NET程序员公开数据访问服务的类 2.ADO.NET的组成部分和对象模型 (1)ADO.NET的两个 ...
- (三) Docker 常用操作与CentOS7 防火墙命令
参考并感谢 Docker 常用命令 https://docs.docker.com/engine/reference/commandline/docker/ Docker 登录docker账户 doc ...
- 查看font字体文件
url: http://bluejamesbond.github.io/CharacterMap/ 打开网址后,如下图操作
- Java High Level REST Client 使用示例
概述 ES 在 7.0 版本开始将废弃 TransportClient,8.0 版本开始将完全移除 TransportClient,取而代之的是 High Level REST Client,官方文档 ...
- 1+X证书学习日志——定位
## 静态定位: position:static; 默认值,指定left/right/top/bottom/ 没有作用. pos ...
- python 数据类型 常用法方
python 数据类型 常用法方 upper() 大写 str lower() 小写 str strip() rstrip() lstrip() 去除字符两边的空格 去右边 左边空白 str repl ...
- HTML Marquee跑马灯
Marquee是html的标签,所有的主流浏览器都能兼容,用于创建文字滚动. 来介绍下标签的属性 滚动方向 direction <!--滚动方向 direction 4个值 up down le ...
- ssh远程登录连接慢的解决方法
近期在搭建自动化集群服务,写脚本ssh批量分发公钥至其它服务器时比较缓慢,便在度娘上寻找解决方法如下: 方法一: 以ssh -v 调试模式远程登录: [root@bqh-nfs- ceshi]# ss ...