首页 > 其他分享 >【CodeChef】3out1in(优先队列)

【CodeChef】3out1in(优先队列)

时间:2024-05-16 15:19:19浏览次数:20  
标签:3out1in 队列 ll 元素 数组 frac 相反数 CodeChef

题目大意:

给出数组a,问对于所有满足\(1\le k\le n\)的奇数\(k\),\(f([a_1,a_2,...,a_k])\)的值。\(f([a_1,a_2,...,a_n])\)的值为对数组\([a_1,a_2,...,a_n]\)进行\(\frac{n+1}{2}\)次操作(选择数组中的三个元素,将其中一个取相反数,然后让它们合并成一个元素)后,数组最后剩下元素的最大值。


考虑数组中每个元素对答案的贡献(答案为所有元素的贡献之和)。

操作之前,数组中第\(i\)个元素对答案的贡献为\(a_i\)。每经过一次操作后,其中一个元素对答案的贡献就会变成相反数(这个元素的贡献变成相反数后不会再通过操作改变贡献)。因此经过\(\frac{k+1}{2}\)次操作之后,会有\(\frac{k+1}{2}\)个元素的贡献变成相反数。

因此,如果我们要让贡献之和最大,只需要将\([a_1,a_2,...,a_k]\)中最小的\(\frac{k+1}{2}\)个元素取相反数即可。

具体实现中,我们可以开两个优先队列。\(k\)从\(1\)枚举到\(n\)的过程中,队列1储存较小的\(\frac{k+1}{2}\)个元素,队列2储存剩下较大的元素。对于每个\(k\),答案即为队列2元素之和减去队列1的元素之和。

#include<bits/stdc++.h>
#define pt printf(">>>")
#define mid (((l)+(r))/2)
using namespace std;
typedef long long ll;
const ll N=1e6+10,inf=1e18+10,mod=1e9+7;
ll n,q,a[N],dp[N];
int main(){
	int T;
	cin >> T;
	while(T--){
		cin >> n >> q;
		for(ll i=1;i<=n;i++)cin >> a[i];
		priority_queue<ll> que1;
		priority_queue<ll,vector<ll>,greater<ll> > que2;
		que1.push(-inf);
		que2.push(a[1]);
		que2.push(inf);
		ll sum1=0,sum2=a[1];
		for(ll i=1;i<=n;i+=2){
			dp[i]=sum2-sum1;
			if(i<n){
				if(a[i+1]<=que1.top())que1.push(a[i+1]),sum1+=a[i+1];
				else que2.push(a[i+1]),sum2+=a[i+1];
				if(a[i+2]<=que1.top())que1.push(a[i+2]),sum1+=a[i+2];
				else que2.push(a[i+2]),sum2+=a[i+2];
				while(que1.size()<i/2+1+1){
					ll v=que2.top();que2.pop();
					que1.push(v);
					sum1+=v,sum2-=v;
				}
				while(que1.size()>i/2+1+1){
					ll v=que1.top();que1.pop();
					que2.push(v);
					sum1-=v,sum2+=v;
				}
			}
		}
		while(q--){
			ll k;
			cin >> k;
			cout << dp[k] << ' ';
		}
		cout << endl;
	}
	return 0;
}

标签:3out1in,队列,ll,元素,数组,frac,相反数,CodeChef
From: https://www.cnblogs.com/alric/p/18196029

相关文章

  • 【CodeChef】Origin(数论)
    题目大意:\(f(x)=\begin{cases}x,1\lex\le9\\f(x的各数位之和),x>9\\\end{cases}\)求\(\sum_{i=1}^{n}f(i)\)。根据打表找规律,我们会发现\(f(x)=(x-1)\bmod9+1\)。所以\(\sum_{i=1}^{n}f(i)\)\(=\sum_{i=1}^{\lfloor\frac{n}{9}\rfloor\cdot9}f(x)+\sum_{i=\l......
  • kombu & celery:如何在Python中舒适地使用消息队列
    Kombu和Celery是Python中的两个库,它们可分开或结合起来使用,以实现基于分布式消息传递的异步任务队列。KombuKombu是一个Python消息库,它为多种消息队列提供了抽象和统一的使用方式。它支持AMQP协议的消息队列服务,如RabbitMQ和Redis,以及其他一些通过插件实现的传输方......
  • 线程安全队列(使用互斥锁进行实现)
    线程安全队列(使用互斥锁进行实现)没有设置队列上限的线程安全队列只需要采取一个std::condition_variable变量,用于处理队列为空的情况以下是示例代码,涉及了std::mutex和std::condition_variable、std::unique_lock、std::lockguard等多线程交互的类。测试方式采取的是3个生成者......
  • PikaScript - 面向嵌入式的超轻量级python引擎+Ring-Buffer - 仅80行代码的超简洁环形
    1、PikaScript-面向嵌入式的超轻量级python引擎PikaScript(前称mimiscript)是一个完全重写的超轻量级python引擎,零依赖,零配置,可以在少于4KB的RAM下运行(如stm32g030c8和stm32f103c8),极易部署和扩展。项目地址:https://github.com/pikasTech/pikascriptPikaScript是使用c语言写......
  • 力扣-232. 用栈实现队列
    1.题目信息2.题解2.1双栈的使用(用栈实现队列)思路我们一开始可能会想到对于每次入栈操作——由于我们可能希望他是加在队尾(栈底)而不是队头(栈首),所以我们就进行一次首尾互换,将instack中的数据倒腾到outstack,由于栈先进后出的特性,所以这时候原来的栈底在头部,我们直接将元素pus......
  • 实现队列 栈 双端队列
    以下都是用list来实现的 实现Stack#ImplementaStackinPythonclassStack(object):def__init__(self):self.items=[]defis_empty(self):returnself.items==[]defpush(self,item):self.items.append(item)d......
  • 算法竞赛第一章-队列
    1、队列constintN=1e5;//定义队列大小intque[N],head,tail;//队头队尾指针,队列大小为tail-head+1//head++;弹出对头,head<=tail//queue[head];//读对头数据//que[++tail]=data;//数据data入队,尾指针加1,注意不能溢出2、STLqueuequeue<Type>q:定义......
  • 深入剖析:如何使用Pulsar和Arthas高效排查消息队列延迟问题
    背景前两天收到业务反馈有一个topic的分区消息堆积了:根据之前的经验来看,要么是业务消费逻辑出现问题导致消费过慢,当然也有小概率是消息队列的Bug(我们使用的是pulsar)。排查通过排查,发现确实是在一点多的时候消息堆积了(后面是修复之后堆积开始下降)。于是我在刚才堆积处查......
  • 队列的实现
    /********************************************************************************************************** filename: Zqh_队列实现.c* author : [email protected]* date : 2024/05/05* function: 实现队列的增删改查* note : 模板* *Copyright(c)......
  • 以数组为基础实现循环队列
    /*****************************************************************name;CirQueue_Create*function:创建循环队列*parameter;unsighedintsize*ReValue;CirQueue_t**author;小北blog*attention;*date;2024.04.26*history;*version;*Copyright(c)......