#对顶堆#nssl 1477 赛
分析
首先按小到大排序,考虑枚举两个都喜欢的个数\(i\)
那么只喜欢一个的个数各需要\(k-i\),剩下要补充到\(m-k*2+i\)个,
考虑用对顶堆维护大根堆大小仅有\(m-k*2+i\)即可
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=200011; typedef long long lll; lll ans=1e18,sum;
int n1,n2,n3,like[N],A[N],B[N],C[N],n,m,k,o[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline lll min(lll a,lll b){return a<b?a:b;}
inline void Swap(int &a,int &b){rr int t=a; a=b; b=t;}
struct Max_Heap{
int cnt,heap[N];
inline void Push(int now){
heap[++cnt]=now;
rr int x=cnt;
while (x>1){
if (heap[x]>heap[x>>1])
Swap(heap[x>>1],heap[x]),x>>=1;
else return;
}
}
inline void Pop(){
heap[1]=heap[cnt--];
rr int x=1;
while ((x<<1)<=cnt){
rr int y=x<<1;
if (y<cnt&&heap[y+1]>heap[y]) ++y;
if (heap[y]>heap[x]) Swap(heap[y],heap[x]),x=y;
else return;
}
}
}heap1;
struct Min_Heap{
int cnt,heap[N];
inline void Push(int now){
heap[++cnt]=now;
rr int x=cnt;
while (x>1){
if (heap[x]<heap[x>>1])
Swap(heap[x>>1],heap[x]),x>>=1;
else return;
}
}
inline void Pop(){
heap[1]=heap[cnt--];
rr int x=1;
while ((x<<1)<=cnt){
rr int y=x<<1;
if (y<cnt&&heap[y+1]<heap[y]) ++y;
if (heap[y]<heap[x]) Swap(heap[y],heap[x]),x=y;
else return;
}
}
}heap2;
signed main(){
n=iut(); m=iut(); k=iut();
for (rr int i=1;i<=n;++i) o[i]=iut();
for (rr int T=iut();T;--T) like[iut()]=1;
for (rr int T=iut();T;--T) like[iut()]|=2;
for (rr int i=1;i<=n;++i){
switch (like[i]){
case 0:heap2.Push(o[i]); break;
case 1:A[++n1]=o[i]; break;
case 2:B[++n2]=o[i]; break;
case 3:C[++n3]=o[i]; break;
}
}
sort(A+1,A+1+n1),sort(B+1,B+1+n2),sort(C+1,C+1+n3);
if (k<n3) for (rr int i=k+1;i<=n3;++i) heap2.Push(C[i]);
for (rr int i=1;i<=n1;++i) sum+=A[i];
for (rr int i=1;i<=n2;++i) sum+=B[i];
rr int j1=n1,j2=n2,len=m-n1-n2;
for (rr int i=0,t=min(n3,k);i<=t;++i,--len){
for (;j1>k-i;--j1,++len) heap2.Push(A[j1]),sum-=A[j1];
for (;j2>k-i;--j2,++len) heap2.Push(B[j2]),sum-=B[j2];
if (j1+i>=k&&j2+i>=k){
for (;len>0&&heap2.cnt;heap2.Pop(),--len)
sum+=heap2.heap[1],heap1.Push(heap2.heap[1]);
if (heap1.cnt&&heap2.cnt)
while (heap1.heap[1]>heap2.heap[1]){
rr int X=heap1.heap[1],Y=heap2.heap[1];
heap1.Pop(),heap2.Pop(),sum+=Y-X;
heap1.Push(Y),heap2.Push(X);
}
if (!len) ans=min(ans,sum);
}
sum+=C[i+1];
}
if (ans==1e18) printf("-1");
else printf("%lld",ans);
return 0;
}
#对顶堆#nssl 1477 赛的更多相关文章
- 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小,我们就维护一个大小为 ...
- bzoj 1112: [POI2008]砖块Klo【对顶堆】
priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...
- 【Luogu P1168】【Luogu P1801&UVA 501】中位数&黑匣子(Black Box)——对顶堆相关
Luogu P1168 Luogu P1801 UVA 501(洛谷Remote Judge) 前置知识:堆.优先队列STL的使用 对顶堆 是一种在线维护第\(k\)小的算法. 其实就是开两个堆,一个 ...
- luogu 3466 对顶堆
显然答案是将一段区间全部转化成了其中位数这样的话,需要维护一个数据结构支持查询当前所有数中位数对顶堆 用两个堆将 < 中位数的数放入大根堆将 > 中位数的数放入小根堆这样就会存在删除操作 ...
随机推荐
- 探秘C语言数组:解锁高效数据管理与多维空间编程技巧"
欢迎大家来到贝蒂大讲堂 养成好习惯,先赞后看哦~ 所属专栏:C语言学习 贝蒂的主页:Betty's blog 引言 前面贝蒂给大家介绍了选择结构与循环结构,今天,贝蒂准备给大家介绍C语言中一个非常重要 ...
- 学习go语言编程之错误处理
error接口 Golang中有一个关于错误处理的标准模式,即:error接口. type error interface { Error() string } 对于大多数函数,如果要返回错误,大致上 ...
- 常用Linux命令备查
查找在指定日期创建的文件 2种方式: find命令: # 这种方式查找到的文件会显示路径 find -name *.log -newermt '2022-06-21 08:00:00' ! -newe ...
- vscode配置远程开发环境
下载vscode 下载好了后,先安装两个插件,商店里面搜索"Chinese",中文语言包, "python"安装包,安装好后重启vscode. 本地的pytho ...
- 数据分析day02
案例 需求:双均线策略制定 1.使用tushare包获取某股票的历史行情数据 2.计算该股票历史数据的5日均线和30日均线 - 什么是均线? - 对于每一个交易日,都可以计算出前N天的移动平均值,然后 ...
- 【Azure API 管理】Azure API Management通过请求中的Path来限定其被访问的频率(如1秒一次)
问题描述 Azure API Management 是否可以通过请求中的Path来限定其被访问的频率? 在系统Request中发现某个Path 在短时间内被频繁的调用,影响了后台服务的性能及安全,所以 ...
- Java toString的使用
1 package com.bytezreo.objectclass; 2 3 import java.util.Date; 4 5 /** 6 * 7 * @Description Object类中 ...
- [VueJsDev] 快速入门 - 开发前小知识
[VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html 开发前小知识 ::: details 目录 目录 开发前小知 ...
- shell脚本中常用的自定义函数
在Shell脚本中,你可以定义各种函数来执行不同的任务.以下是20个常用的自定义函数示例,涵盖了从文件操作.文本处理到系统监控等多个方面: 检查文件是否存在 file_exists() { [ -f ...
- python 文件操作常用方法
一 python文件创建 import os import argparse def file_write(file_name,msg): f = open(file_name,"a&quo ...