AcWing 蚯蚓 三个队列的维护

原题链接:https://www.acwing.com/problem/content/description/135/

思路:

1.如果q=0,即蚯蚓不会变长,那么就只是每次查询最大值,插入新的值。相当于维护一个集合。

2.如果q>0,那么每次选择最长的蚯蚓切断后,新产生的蚯蚓长度分别为px和x-px,并且其余蚯蚓会变长q,那么为了方便维护,我们设新产生的两只蚯蚓的长度分别为px-q和x-px-q,那么我们就可以对整个集合加上q。那么如何选择每次的最长的蚯蚓呢?我们可以建立三个队列,分别存储原来集合的蚯蚓(先按从大到小排序),新产生的px的蚯蚓,新产生的x-px的蚯蚓。由于每次选的都是最大值,因为p在0-1之间,并且这次的最大值选了,下次的肯定没这次大,所以新产生的两个蚯蚓集合同样满足递减规律,因此每次的最大值必是三个队首元素之一。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,q,u,v,t;
#define p u/v
const int maxn = 1e7+10;
ll f[maxn];
queue<ll>  q1,q2,q3;
int cmp(int x, int y){
	return x>y;
}
ll work(ll t){
	ll x=-1,a=-1,b=-1,c=-1;
	if(!q1.empty()) a=q1.front()+t*q;//然后把整个集合都加上q 
	if(!q2.empty()) b=q2.front()+t*q;
	if(!q3.empty()) c=q3.front()+t*q;
	x=max(a,max(b,c));
	if(x==a) q1.pop();
	else if(x==b) q2.pop();
	else q3.pop();
	return x;//找出最大值 
}
int main(){
	cin>>n>>m>>q>>u>>v>>t;
	for(int i=1;i<=n;i++){
		cin>>f[i];
	}
	sort(f+1,f+1+n,cmp);//从大到小排序 
	for(int i=1;i<=n;i++){
		q1.push(f[i]);
	}
	for(int i=1;i<=m;i++){
		ll x=work(i-1);//找出每个时刻的最大值
		if(!(i%t)) cout<<x<<" ";//输出格式 
		ll now1=x*p;
		ll now2=x-now1;
		//不妨设产生了两个大小为px-q和x-px-q的新数 
		q2.push(now1-i*q);
		q3.push(now2-i*q);
		
	}
	cout<<endl;
	for(int i=1;i<=(n+m);i++){//输出所有蚯蚓的长度 
		ll x=work(m);
		if(i%t==0) cout<<x<<" ";
	}
	return 0;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值