P2827题解
题面:
分析:
注意到 \(p,q\) 是固定常熟,\(0<p<1\) 且 \(q\) 是非负整数。
设 \(x_1,x_2\) 为非负整数且 \(x_1\ge x_2\) :
\(\therefore\left\lfloor px_1\right\rfloor+q=\left\lfloor px_1+q\right\rfloor\ge \left\lfloor px_2+pq\right\rfloor=\left\lfloor p(x_2+q)\right\rfloor\\\because x_1-x_2>p(x_1-x_2)\\\therefore x_1-px_1>x_2-px_2\ge x_2-p(x_2+q)\\\therefore x_1-\left\lfloor px_1\right\rfloor +q=\left\lfloor x_1-px_1\right\rfloor +q\ge \left\lfloor x_2-p(x_2+q)\right\rfloor+q=x_2+q-\left\lfloor p(x_2+q)\right\rfloor\)
根据上面推出来的结论,我们可以发现,若 \(x_1\) 在 \(x_2\) 之前取出,则一秒后由 \(x_1\) 产生的两个数 \(\left\lfloor px_1\right\rfloor+q\) 和 \(x_1-\left\lfloor px_1\right\rfloor+q\) 分别大于等于由 \(x_2+q\) 产生的两个数 \(\left\lfloor p(x_2+q)\right\rfloor\) 和 \(x_2+q-\left\lfloor p(x_2+q)\right\rfloor\)。
因此,若从集合中取出的数是单调递减的,则新产生的数也随着时间单调递减。
因此,我们可以建立三个队列 \(A,B,C\)(其中队列 \(A\) 为大根堆)。队列 \(A\) 存原序列,队列 \(B\) 存产生的第一个数值,队列 \(C\) 存产生的第二个数值。显然,三个队列都是单调递减的,因此每个时刻的最大值是三个队列的队首之一。
在这个结论的基础上,我们维护一个偏移量 \(delta\),使集合中的每一个数加上 \(delta\) 便是它的真实数值。在计算时将集合中的数加上 \(delta\) 即可。
Code:
/*
user:xcj
time:2022.4.8
*/
#include <bits/stdc++.h>
#define int long long
using namespace std;
priority_queue < int > q;
queue < int > q1, q2;
int n, m, k, u, v, t, delta;
inline int read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
signed main(){
n = read(), m = read(), k = read(), u = read(), v = read(), t = read();
for (int i = 1, x; i <= n; ++i) x = read(), q.push(x);
for (int i = 1, f, maxn; i <= m; ++i){
maxn = -2147482597;
if (q.size() && q.top() > maxn) maxn = q.top(), f = 0;
if (q1.size() && q1.front() > maxn) maxn = q1.front(), f = 1;
if (q2.size() && q2.front() > maxn) maxn = q2.front(), f = 2;
if (!f) q.pop();
else if (f < 2) q1.pop();
else q2.pop();
maxn += delta;
q1.push(maxn * u / v - delta - k), q2.push(maxn - maxn * u / v - delta - k);
delta += k;
if (i % t == 0) printf("%lld ", maxn);
}
puts("");
for (int i = 1, maxn, f; i <= n + m; ++i){
maxn = -2147482597;
if (q.size() && q.top() > maxn) maxn = q.top(), f = 0;
if (q1.size() && q1.front() > maxn) maxn = q1.front(), f = 1;
if (q2.size() && q2.front() > maxn) maxn = q2.front(), f = 2;
if (!f) q.pop();
else if (f < 2) q1.pop();
else q2.pop();
if (i % t == 0) printf("%lld ", maxn + delta);
}
puts("");
return 0;
}
浙公网安备 33010602011771号