本来不想写这题题解的,考虑到P6033合并果子(加强版)和这题的共同点,写了这篇题解
题面
https://www.luogu.com.cn/problem/P2827
复制粘贴真的累QAQ,LaTeX复制不过来,心疼一下我。。
题解
说了和P6033很像,因为P6033是用两个队列维护有序数组,而这题是用三个。
然后就没了。
而用队列维护有序数组这个套路,其实就是利用原本的一些单调性,然后用类似归并排序时合并两个单调数组的方法,每次比较队列的开头,支持每次查询最大/最小值,算是一个套路了,在这篇博客里记录一下。
还是放一下题解代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
const int M1 = 1e5 + 5;
const int M2 = 8e6;
using namespace std;
int a[M1];
int b[M2];
int c[M2];
bool cmp(int x,int y)
{
return x > y;
}
int main()
{
int n,m,qq,u,v,t;
//n:蚯蚓数 ; m : m秒内的状况 ; q :其余蚯蚓增加的长度
int qwq;
scanf("%d%d%d%d%d%d",&n,&m,&qq,&u,&v,&t);
a[n + 1] = -0x7fffffff;
double p;
p = u * 1.0 / v;
for(int i = 1;i <= n;++ i)
scanf("%d",&a[i]);
sort(a + 1,a + n + 1,cmp);
int js = 0;
int ja = 1;
int jb = 1,tb = 0;
int jc = 1,tc = 0;
int Max;
int zuobiao;
while(m --)
{
if(a[ja] >= b[jb] && a[ja] >= c[jc])
{
Max = a[ja];
ja ++;
}
else
if(b[jb] >= a[ja] && b[jb] >= c[jc])
{
Max = b[jb];
jb ++;
}
else
if(c[jc] >= a[ja] && c[jc] >= b[jb])
{
Max = c[jc];
jc ++;
}
int awa = Max + js * qq;
js ++;
if(js % t == 0)
printf("%d ",awa);
int X1 = awa * p;
b[++ tb] = X1 - js * qq;
c[++ tc] = (awa - X1) - js * qq;
}
printf("\n");
int ans = 0;
for(int i = ja;i <= n;++ i)a[i] += qq * js;
for(int i = jb;i <= tb;++ i)b[i] += qq * js;
for(int i = jc;i <= tc;++ i)c[i] += qq * js;
b[tb + 1] = -0x7fffffff;
c[tc + 1] = -0x7fffffff;
while(ja <= n || jb <= tb || jc <= tc)
{
ans ++;
if(a[ja] >= b[jb] && a[ja] >= c[jc] && ja <= n)
{
if(ans % t == 0)
printf("%d ",a[ja]);
ja ++;
}
else
if(b[jb] >= a[ja] && b[jb] >= c[jc] && jb <= tb)
{
if(ans % t == 0)
printf("%d ",b[jb]);
jb ++;
}
else
if(c[jc] >= a[ja] && c[jc] >= b[jb] && jc <= tc)
{
if(ans % t == 0)
printf("%d ",c[jc]);
jc ++;
}
}
printf("\n");
return 0;
}