• #对顶堆#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;
    }
    
  • 相关阅读:
    结对作业
    小学算术题四则运算(升级)
    自动生成小学四则运算题目(Python实现)
    《基于CMMI的软件工程及实训指导》第一章 软件工程基础
    使用 python 进行微信好友分析
    中国大学排名
    python小程序测试
    爬虫测试
    体育竞技分析

  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13504546.html
Copyright © 2020-2023  润新知