洛谷 P2827 题解

[NOIP 2016 提高组] 蚯蚓

我们定义初始时的蚯蚓叫做原蚯蚓,切断后分裂出来的蚯蚓叫做新蚯蚓。

我们把原蚯蚓排序。可以证明新蚯蚓也有序,具体见这篇题解

既然除了最新的新蚯蚓每个蚯蚓都会增加 \(p\),我们就不用单独为每个蚯蚓增加了。我们只需要把刚生成的新蚯蚓减去 \(p\) 即可。然后我们计算实际的值与存储的值之差。

具体实现:我们开三个队列,一个记录原蚯蚓(排好序),一个记录 \(\lfloor px\rfloor\),一个记录 \(x-\lfloor px\rfloor\)。每次取出三个队列的队头,取最大的一个作为此次的 \(x\),并从所在的队列里弹出。然后我们取实际的 \(x\)(即 \(x+q(i-1)\)),将其切割为 \(\lfloor px\rfloor\)\(x-\lfloor px\rfloor\) 两段。分别放入队列时要减去 \(qi\)

AC code:

#include<bits/stdc++.h>
using namespace std;
const signed N=1e5+5;
typedef long long ll;
queue<ll> b,c;
ll a[N],Top;
signed n;
ll m,q,u,v,t;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m>>q>>u>>v>>t;
	a[0]=-1e18;
	for(signed i=1;i<=n;i++){
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	Top=n;
	for(ll i=1;i<=m;i++){
		ll x=a[Top];
		signed y=1;
		if(b.size()&&b.front()>x){
			x=b.front();
			y=2;
		}
		if(c.size()&&c.front()>x){
			x=c.front();
			y=3;
		}
		if(y==1) Top--;
		else if(y==2) b.pop();
		else if(y==3) c.pop();
		x=x+q*(i-1);
		if(i%t==0) cout<<x<<' ';
		b.push(x*u/v-q*i);c.push(x-x*u/v-q*i);
	}
	cout<<'\n';
	for(ll i=1;Top||b.size()||c.size();i++){
		ll x=a[Top];
		signed y=1;
		if(b.size()&&b.front()>x){
			x=b.front();
			y=2;
		}
		if(c.size()&&c.front()>x){
			x=c.front();
			y=3;
		}
		if(y==1) Top--;
		else if(y==2) b.pop();
		else if(y==3) c.pop();
		if(i%t==0) cout<<x+q*m<<' ';
	}
	cout<<'\n';
	return 0;
}
posted @ 2025-11-22 11:53  NiYqaq  阅读(25)  评论(0)    收藏  举报