显然答案是将一段区间全部转化成了其中位数
这样的话,需要维护一个数据结构支持查询当前所有数中位数
对顶堆
用两个堆
将 < 中位数的数放入大根堆
将 > 中位数的数放入小根堆
这样就会存在删除操作
删除的时候
由于无法快速删除
只需做个标记,标记该数被删除了一次
并且堆的实际大小也应该另外记录维护
在标记时需要更改相应的堆的大小与权值
答案就非常显然了

#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 对顶堆的更多相关文章

  1. 【Luogu P1168】【Luogu P1801&UVA 501】中位数&黑匣子(Black Box)——对顶堆相关

    Luogu P1168 Luogu P1801 UVA 501(洛谷Remote Judge) 前置知识:堆.优先队列STL的使用 对顶堆 是一种在线维护第\(k\)小的算法. 其实就是开两个堆,一个 ...

  2. Luogu 3466 [POI2008]KLO-Building blocks

    BZOJ 1112. 题意相当于在一个长度为$k$的区间内选择一个数$s$使$\sum_{i = 1}^{k}\left | a_i - s \right |$最小. 很显然是中位数. 然后只要写一个 ...

  3. hdu3282 链表或者对顶堆

    维护序列的动态中位数 第一次用链表做题..感觉指针指来指去也挺麻烦的.. 本题链表解法就是用数组模拟出一个链表,然后离线输入所有数,排序,按照输入顺序在链表里删除元素,一次性删掉两个,然后中位数指针对 ...

  4. 【uoj#280】[UTR #2]题目难度提升 对顶堆+STL-set

    题目描述 给出 $n$ 个数 $a_1,a_2,...,a_n$ ,将其排为序列 $\{p_i\}$ ,满足 $\{前\ i\ 个数的中位数\}$ 单调不降.求字典序最大的 $\{p_i\}$ . 其 ...

  5. hdu4261 Estimation[暴力dp+对顶堆]

    https://vjudge.net/problem/HDU-4261 对于一个长2000的数列划分最多25个块,每块代价为块内每个数与块内中位数差的绝对值之和,求最小总代价. 套路化地,设$f[i] ...

  6. 【POJ 3784】 Running Median (对顶堆)

    Running Median Description For this problem, you will write a program that reads in a sequence of 32 ...

  7. P1168 中位数(对顶堆)

    题意:维护一个序列,两种操作 1.插入一个数 2.输出中位数(若长度为偶数,输出中间两个较小的那个) 对顶堆 维护一个小根堆,一个大根堆,大根堆存1--mid,小根堆存mid+1---n 这样堆顶必有 ...

  8. poj3784 Running Median[对顶堆]

    由于我不会讲对顶堆,所以这里直接传上一个巨佬的学习笔记. 对顶堆其实还是很容易理解的,想这题的时候自己猜做法也能把没学过的对顶堆给想出来.后来了解,对顶堆主要还是动态的在线维护集合$K$大值.当然也可 ...

  9. 洛谷 - P1801 - 黑匣子 - 对顶堆

    这道题是提高+省选-的难度,做出来的话对数据结构题目的理解会增加很多. 可以使用一种叫做对顶堆的东西,对顶堆是在线维护第n小的logn的算法.大概的思路是,假如我们要找的是第n小,我们就维护一个大小为 ...

随机推荐

  1. PB对象Event ID说明

    原地址:https://www.cnblogs.com/nickflyrong/p/5973795.html Event ID 含义 内容浅析 event可以用pb自带的id,自动触发事件,而func ...

  2. 作业调度框架Quartz.NET-现学现用-01-快速入门

    原文:作业调度框架Quartz.NET-现学现用-01-快速入门 前言 你需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行.一个自动执行而无须干预的任务在执 ...

  3. Spring AOP 创建Advice 基于Annotation

    public interface IHello { public void sayHello(String str); } public class Hello implements IHello { ...

  4. SQL*Plus 与数据库的交互(SQL*Plus时什么)

    Oracle 的 SQL*Plus 是与数据库进行交互的客户端工具,在 SQL*Plus中,可以运行 SQL*Plus 命令与 SQL*Plus 语句.   SQL*Plus 时一个基于 C/S 两层 ...

  5. Ubuntu安装KScope

    命令安装 # apt-get install kscope 1. 编译安装 # tar xvf kscope-1.9.4.tar.gz # cd kscope-1.9.4 # qmake # make ...

  6. 微信小程序实现下拉刷新上拉加载

    代码片段:https://developers.weixin.qq.com/s/K9VbWZmy7e8C

  7. LAMP环境搭建之编译安装指南(php-5.3.27.tar.gz)

    测试环境:CentOS release 6.5 (Final) 软件安装:httpd-2.2.27.tar.gz   mysql-5.1.72.tar.gz   php-5.3.27.tar.gz 1 ...

  8. 【JUC】7.CountDownLatch

    Latch:门闩.一种线程通信的方式:当程序不涉及同步,仅仅需要线程通信的时候,使用synchronize或者lock的线程通信等待唤醒机制,就显得太重了: 这时候,可以考虑使用信号量类:CountD ...

  9. Android自动化测试探索(一)adb详细介绍

    adb详细介绍 #1. 基本简介 adb,即Android Debug Bridge,它是Android开发/测试人员不可替代的强大工具 #2. Mac上安装adb 安装brew /usr/bin/r ...

  10. ipsec][strongswan] ipsec SA创建失败后的错误处理分析

    〇 ike协商的过程最终是为了SA的建立, SA的建立后, 在底层中管理过程,也是相对比较复杂的. 这里边也经常会出现失败的情况. 我们以strongswan为例, 在strongswan的底层SA管 ...