洛谷 P2827 题解
我们定义初始时的蚯蚓叫做原蚯蚓,切断后分裂出来的蚯蚓叫做新蚯蚓。
我们把原蚯蚓排序。可以证明新蚯蚓也有序,具体见这篇题解。
既然除了最新的新蚯蚓每个蚯蚓都会增加 \(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;
}

浙公网安备 33010602011771号