AcWing 133 蚯蚓 (队列)
https://www.acwing.com/problem/content/description/135/
优先队列,每次将最长的蚯蚓取出来,切开后减去当前的偏移量,再放回队列
但 \(m\) 的范围是 \(7e6\),显然需要线性做法
线性做法,那就需要考虑一下蚯蚓长度的单调性了,
可以证明,如果 \(x1 > x2\) ,那么新产生的两个蚯蚓长度也是单调递减的
所以就可以维护三个长度递减的队列,每次记得加上偏移量即可
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 100010;
int n, m, Q, v, u, t, delta;
double p;
int a[maxn];
queue<int> q[4];
vector<int> ans1, ans2;
bool cmp(int a, int b){ return a > b; }
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
delta = 0;
n = read(), m = read(), Q = read(), u = read(), v = read(), t = read();
p = (1.0 * u) / (1.0 * v);
for(int i=1;i<=n;++i) a[i] = read();
sort(a + 1, a + 1 + n, cmp);
for(int i=1;i<=n;++i) q[0].push(a[i]);
int num, x, part1, part2;
if(m!=0){
x = q[0].front();
q[0].pop();
part1 = p * x;
part2 = x - part1;
delta = Q;
q[1].push(part1 - delta);
q[2].push(part2 - delta);
if(t == 1) ans1.push_back(x);
for(int i=2;i<=m;++i){
if(!q[0].empty()) num = 0, x = q[0].front();
else num = 1, x = q[1].front();
if(q[1].front() > x){
x = q[1].front();
num = 1;
}
if(q[2].front() > x){
x = q[2].front();
num = 2;
}
q[num].pop();
if(i % t == 0) ans1.push_back(x + delta);
part1 = p * (x + delta);
part2 = (x + delta) - part1;
delta += Q;
q[1].push(part1 - delta);
q[2].push(part2 - delta);
}
int num, x;
while(!q[0].empty() || !q[1].empty() || !q[2].empty()){
if(!q[0].empty()) num = 0, x = q[0].front();
else if(!q[1].empty()) num = 1, x = q[1].front();
else num = 2, x = q[2].front();
if(!q[1].empty() && q[1].front() > x){
x = q[1].front();
num = 1;
}
if(!q[2].empty() && q[2].front() > x){
x = q[2].front();
num = 2;
}
ans2.push_back(x + delta);
q[num].pop();
}
for(int i=0;i<ans1.size();++i){
printf("%d ",ans1[i]);
}printf("\n");
for(int i=0;i<ans2.size();++i){
if((i+1) % t == 0) printf("%d ",ans2[i]);
}printf("\n");
}else{
printf("\n");
for(int i=1;i<=n;++i) if(i % t == 0) printf("%d ",a[i]); printf("\n");
}
return 0;
}