分析

首先按小到大排序,考虑枚举两个都喜欢的个数\(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 赛的更多相关文章

  1. hdu3282 链表或者对顶堆

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

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

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

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

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

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

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

  5. P1168 中位数(对顶堆)

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

  6. poj3784 Running Median[对顶堆]

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

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

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

  8. bzoj 1112: [POI2008]砖块Klo【对顶堆】

    priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...

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

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

  10. luogu 3466 对顶堆

    显然答案是将一段区间全部转化成了其中位数这样的话,需要维护一个数据结构支持查询当前所有数中位数对顶堆 用两个堆将 < 中位数的数放入大根堆将 > 中位数的数放入小根堆这样就会存在删除操作 ...

随机推荐

  1. queryset高级用法:select_related

    在提取某个模型的数据的同时,也提前将相关联的数据提取出来.比如提取文章数据,可以使用select_related将author信息提取出来,以后再次使用article.author的时候就不需要再次去 ...

  2. pexpect模块(替代subprocess)

    https://blog.csdn.net/pcn01/article/details/104993742/

  3. Kotlin 协程五 —— 在Android 中使用 Kotlin 协程

    目录 一.Android MVVM 结构 二.添加依赖 三.在后台线程中执行 3.1 协程解决了什么问题 3.2 保证主线程安全 3.3 withContext 的性能 四.结构化并发 4.1 追踪协 ...

  4. 【LeetCode贪心#04】跳跃游戏I + II

    跳跃游戏 力扣题目链接(opens new window) 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示 ...

  5. 使用objc4V818.2源码编译,没有什么比苹果底层源码更有说服力去证明底层原理真假

    前言 为什么会想要调试源码? 苹果开源了部分源码, 但相似内容太多, 基本找不到代码见的对应关系, 如果能像自己工程一样进行跳转那多好哇~~ 苹果源码开源地址: https://opensource. ...

  6. 谈一谈如何使用etcd中的事务

    本文内容来源于自己学习时所做的记录,主要来源于文章最后的参考链接,如有侵权,请联系删除,谢谢! etcd 是一个 key/value 类型的数据库.既然我们需要存储数据,必然会面临这样一个需求,即希望 ...

  7. 亲测可用,ChatGPT 对话技巧

      "Linux终端" "我希望你充当一个 linux 终端.我会输入命令,你会回复终端应该显示的内容.我希望你只回复一个唯一代码块内的终端输出,没有别的.不要写解释.除 ...

  8. 影刀rpa:关于if单条件切换到多条件时的不便之处

    现有需求,只判断一个条件是否满足即可,但随着后续业务开发,这里得if就需要判断多个条件,此时要是想将if单条件改为多条件的话,就得先拉一个if多条件的指令,然后再将if单条件中的语句全部移动到if多条 ...

  9. 【Flink入门修炼】2-2 Flink State 状态

    什么是状态?状态有什么作用? 如果你来设计,对于一个流式服务,如何根据不断输入的数据计算呢? 又如何做故障恢复呢? 一.为什么要管理状态 流计算不像批计算,数据是持续流入的,而不是一个确定的数据集.在 ...

  10. Server-side template injection 模板注入问题总结

    概念: 服务器模板注入(Server-side template injection) 攻击者能够使用本地的模板语法去注入一个恶意的payload,然后在服务器端执行该攻击,当与欧股直接输入数据到模板 ...