题意
题解
容易想到使用二叉堆维护长度的最大值,由于每次新产生之外的蚯蚓长度都增加 q q q,而难以修改已经在堆中的元素,那么对新产生的蚯蚓长度减 q q q,可以使长度的相互关系保持不变。时间复杂度 O ( m log n ) O(m\log n) O(mlogn),显然难以胜任。
设当前切割蚯蚓长度为 x 1 x_1 x1,那么新增蚯蚓长度分别为 ⌊ p x 1 ⌋ \lfloor px_1\rfloor ⌊px1⌋ 与 x 1 − ⌊ p x 1 ⌋ x_1-\lfloor px_1\rfloor x1−⌊px1⌋。那么下一次可能的切割蚯蚓显然为之前未切割的蚯蚓的长度最大值与新增蚯蚓长度,假设下一次切割的蚯蚓长度为 x 2 x_2 x2,那么有 x 1 ≥ x 2 x_1\geq x_2 x1≥x2,且满足
{
⌊
p
x
1
⌋
+
q
=
⌊
p
x
1
+
q
⌋
≥
⌊
p
(
x
2
+
q
)
⌋
x
1
−
⌊
p
x
1
⌋
+
q
≥
x
1
−
⌊
p
(
x
1
+
q
)
⌋
+
q
≥
x
2
−
⌊
p
(
x
2
+
q
)
⌋
+
q
\begin{cases} \lfloor px_1\rfloor+q=\lfloor px_1+q\rfloor\geq \lfloor p(x_2+q)\rfloor \\ x_1-\lfloor px_1\rfloor+q\geq x_1-\lfloor p(x_1+q)\rfloor+q\geq x_2-\lfloor p(x_2+q)\rfloor+q\\ \end{cases}
{⌊px1⌋+q=⌊px1+q⌋≥⌊p(x2+q)⌋x1−⌊px1⌋+q≥x1−⌊p(x1+q)⌋+q≥x2−⌊p(x2+q)⌋+q 第
2
2
2 个不等式中
x
−
⌊
p
(
x
+
q
)
⌋
,
x
∈
Z
+
x-\lfloor p(x+q)\rfloor,x\in \Z^+
x−⌊p(x+q)⌋,x∈Z+ 的单调性可通过将整数
x
x
x 移入取整符号进行证明,已知
0
<
1
−
p
<
1
0<1-p<1
0<1−p<1,那么有
x
1
−
⌊
p
(
x
1
+
q
)
⌋
≥
⌊
(
1
−
p
)
x
1
−
p
q
)
⌋
≥
⌊
(
1
−
p
)
x
2
−
p
q
)
⌋
≥
x
2
−
⌊
p
(
x
2
+
q
)
⌋
x_1-\lfloor p(x_1+q)\rfloor\geq \lfloor (1-p)x_1-pq)\rfloor\geq \lfloor (1-p)x_2-pq)\rfloor\geq x_2-\lfloor p(x_2+q)\rfloor
x1−⌊p(x1+q)⌋≥⌊(1−p)x1−pq)⌋≥⌊(1−p)x2−pq)⌋≥x2−⌊p(x2+q)⌋ 证明了每一次新增的蚯蚓长度
⌊
p
(
x
2
+
q
)
⌋
\lfloor p(x_2+q)\rfloor
⌊p(x2+q)⌋ 与
x
2
−
⌊
p
(
x
2
+
q
)
⌋
+
q
x_2-\lfloor p(x_2+q)\rfloor+q
x2−⌊p(x2+q)⌋+q 分别不大于上一次切割新增的
⌊
p
x
1
⌋
+
q
\lfloor px_1\rfloor+q
⌊px1⌋+q 与
x
1
−
⌊
p
x
1
⌋
+
q
x_1-\lfloor px_1\rfloor+q
x1−⌊px1⌋+q。那么可以建立
3
3
3 个队列,分别维护有序的初始值、新增的
⌊
p
x
1
⌋
\lfloor px_1\rfloor
⌊px1⌋ 部分与
x
1
−
⌊
p
x
1
⌋
x_1-\lfloor px_1\rfloor
x1−⌊px1⌋ 部分,此时各队列保持有序,下一次切割长度为
3
3
3 个队首元素的最大值。时间复杂度
O
(
n
log
n
+
m
)
O(n\log n + m)
O(nlogn+m)。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005, maxm = 7000005, inf = 0x7fffffff;
int A[maxn], cut[maxm], rem[maxm + maxn];
queue<int> X, Y, Z;
int get()
{
int x = X.size() ? X.front() : -inf, k = 0;
if (Y.size() && Y.front() > x)
x = Y.front(), k = 1;
if (Z.size() && Z.front() > x)
x = Z.front(), k = 2;
if (k == 0)
X.pop();
else if (k == 1)
Y.pop();
else
Z.pop();
return x;
}
int main()
{
int n, m, q, u, v, t;
scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t);
double p = (double)u / v;
for (int i = 1; i <= n; ++i)
scanf("%d", A + i);
sort(A + 1, A + n + 1);
for (int i = n; i; --i)
X.push(A[i]);
int d = 0;
for (int i = 1; i <= m; ++i)
{
int x = get() + d;
cut[i] = x;
d += q;
int y = x * p, z = x - y;
Y.push(y - d);
Z.push(z - d);
}
for (int i = 1; i <= n + m; ++i)
rem[i] = get() + d;
for (int i = t; i <= m; i += t)
printf("%d ", cut[i]);
puts("");
for (int i = t; i <= m + n; i += t)
printf("%d ", rem[i]);
puts("");
return 0;
}