题解:洛谷 P9976 Farmer John Actually Farms
【题目来源】
洛谷:P9976 [USACO23DEC] Farmer John Actually Farms B - 洛谷
【题目描述】
Farmer John 在他的农场上种植了 \(N\)(\(1 \leq N \leq 2\cdot 10^5\))株芦笋!然而,其中有一些植物存在基因差异,长得比其他植物快。第 \(i\) 株植物的初始高度为 \(h_i\) 英寸,之后每天,第 \(i\) 株植物长高 \(a_i\) 英寸。
FJ 更加钟爱其中的一些植物。他将给你一组由不同整数组成的数组 \(t_1,\dots,t_N\),这个数组包含 \(0\) 到 \(N-1\) 的全部整数。他希望恰好有 \(t_i\) 株植物比第 \(i\) 株植物高。找到最少要经过多少天,才能满足 FJ 的要求,或者报告这个要求是不可能满足的。
【输入】
每个测试点中包含多组测试数据。
第一行为一个整数 \(T\),代表测试数据组数(\(1 \leq T \leq 10\))。
对于每一组测试数据,第一行一个整数 \(N\)(\(1 \leq N \leq 2\cdot 10^5\)),表示植物数量。
第二行包含 \(N\) 个整数 \(h_i\)(\(1 \leq h_i \leq 10^9\)),表示第 \(i\) 株植物的初始高度。
第三行包含 \(N\) 个整数 \(a_i\)(\(1 \leq a_i \leq 10^9\)),表示第 \(i\) 株植物每天增长的高度。
第四行包含 \(N\) 个不同的整数 \(t_i\),表示 FJ 给你的数组。
保证所有测试数据的 \(N\) 的和不超过 \(2\cdot 10^5\)。
【输出】
输出 \(T\) 行,每行表示一组测试数据的答案。如果要求不可能满足,输出 \(-1\)。
请注意,由于这个问题涉及的整数大小较大,可能需要使用 64 位整数数据类型(例如,在 C/C++ 中使用 long long 类型)。
【输入样例】
6
1
10
1
0
2
7 3
8 10
1 0
2
3 6
10 8
0 1
2
7 3
8 9
1 0
2
7 7
8 8
0 1
2
7 3
8 8
1 0
【输出样例】
0
3
2
5
-1
-1
【核心思想】
-
问题分析:有 \(N\) 株植物,每株初始高度 \(h_i\),每日生长 \(a_i\)。给定目标排名数组 \(t_i\)(\(t_i\) 表示最终恰好有 \(t_i\) 株植物比第 \(i\) 株高),求满足所有植物排名要求的最小天数 \(d\),或判断不可能。由于 \(t_i\) 是 \(0 \sim N-1\) 的一个排列,因此排名要求等价于:按最终高度从低到高排序后,每株植物的位置必须等于 \(t_i\)。也就是说,最终高度的相对顺序是固定的(由 \(t_i\) 决定)。问题转化为:找到最小的 \(d\),使得对所有植物按 \(t_i\) 排序后,其高度 \(H_i(d) = h_i + a_i \cdot d\) 严格递增。
-
算法选择:
- 排序 + 不等式约束:将植物按 \(t_i\) 从小到大排序(即最终高度从低到高的顺序)。对于排序后相邻的两株植物 \(i\) 和 \(i+1\),必须满足 \(H_i(d) < H_{i+1}(d)\)。这给出了关于 \(d\) 的不等式,每个不等式形如 \((a_i - a_{i+1}) \cdot d < h_{i+1} - h_i\)。根据不同情况(\(a_i\) 与 \(a_{i+1}\) 的大小),可以得到 \(d\) 的下界或上界,或无解。最终取所有下界的最大值和所有上界的最小值,若下界 \(\le\) 上界则可行,最小天数为下界(若为负数则取 0)。
-
关键步骤(基于代码逻辑):
- 读入并排序:将植物按 \(t\) 值从小到大排序(排序后,\(t_i\) 即为索引位置)。
- 初始化:
maxn = 0(下界),minn = INF(上界)。 - 遍历相邻对:对于 \(i\) 从 1 到 \(N-1\),设 \(a = h_i, b = a_i, c = h_{i+1}, d = a_{i+1}\)。需要满足 \(a + b \cdot x < c + d \cdot x\),即 \((b - d) \cdot x < c - a\),其中 \(x\) 为天数。
- 若 \(b == d\):则不等式变为 \(0 < c - a\)。若 \(a \ge c\),则永远无法满足,输出 -1;若 \(a < c\),则恒成立。
- 若 \(b > d\):\(x < \frac{c - a}{b - d}\) 且需满足 \(a < c\) 才能在某天追上。计算下界 \(x = \lfloor (c-a)/(b-d) \rfloor + 1\),更新
maxn。 - 若 \(b < d\):\(x > \frac{c - a}{d - b}\),若 \(a > c\),则计算上界 \(x = \lfloor (a-c-1)/(d-b) \rfloor\),更新
minn;若 \(a \le c\),则 \(i\) 永远比 \(i+1\) 矮,正符合排序要求,无额外约束。
- 判断可行性:若
maxn > minn,则无解输出 -1;否则输出maxn(最小天数)。
-
时间/空间复杂度:
- 时间复杂度:\(O(N \log N)\),主要来自排序。
- 空间复杂度:\(O(N)\)。
-
排序 + 不等式约束的核心思想:
- 排名转顺序:将每株植物的目标排名 \(t_i\) 看作其最终在高度排序中的位置。按 \(t_i\) 排序后,相邻植物的高度必须严格递增。
- 线性函数比较:每株植物高度是 \(d\) 的一次函数 \(h_i + a_i d\)。两个一次函数的大小关系随 \(d\) 变化最多改变一次,因此约束可转化为 \(d\) 的区间(下界或上界)。
- 区间交:所有约束的交集即为可行天数集合。若交集非空,最小天数即为下界的最大值(至少为 0)。
- 严格不等式的整数处理:对于 \(a + b x < c + d x\),移项后需注意除法和取整方向,确保严格不等号成立。
- 适用场景:适用于多个线性增长实体,要求其在某个时间点满足特定排序,且排名由 \(t\) 数组给定。核心是利用线性函数的单调性转化为区间约束。
【解题思路】

【算法标签】
普及 #数学
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int T, n;
struct node {
long long h, a, t;
}p[200005];
bool cmp (node x, node y){
return x.t<y.t;
}
int main()
{
cin >> T; // 输入T
while (T--) { // 遍历T次询问
cin >> n; // 输入n
for (int i=1; i<=n; i++) cin >> p[i].h; // 使用结构体数组,记录每个植物的h、a和t
for (int i=1; i<=n; i++) cin >> p[i].a;
for (int i=1; i<=n; i++) cin >> p[i].t;
if (n==1) { // 如果n==1特判,输出0
cout << 0 << endl;
continue;
}
int minn=1e9, maxn=-1e9; // 定义满足条件的最大值和最小值
sort(p+1, p+n+1, cmp); // 按照t从小到大方式排序
int mark=0; // 定义标记位
for (int i=1; i<n; i++) { // 遍历n-1个植物
int a=p[i].h, b=p[i].a, c=p[i+1].h, d=p[i+1].a; // 定义变量简化代码长度
if (b==d) { // 当b==d时
if (a<=c) { // 如果a小于等于c,永远无法追上,输出-1
cout << -1 << endl;
mark = 1;
break;
} else { // 否则,只需0天就可以满足
maxn = max(maxn, 0);
}
}
if (b>d) { // 当b>d时
if (a<=c) { // 如果a小于等于c,则在某天之后就一直超越
int x = (c-a)/(b-d)+1; // 相减后相除的结果是相等的情况,还需要再加1
maxn = max(maxn, x);
} else { // 否则,只需0天就可以满足
maxn = max(maxn, 0);
}
}
if (b<d) { // 当b<d时
if (a<=c) { // 如果a小于等于c,永远无法追上,输出-1
cout << -1 << endl;
mark=1;
break;
} else {
int x = (a-c-1)/(d-b); // 否则开始超越,但到某天后就不再满足
maxn = max(maxn, 0);
minn = min(minn, x); // 记录该minn
}
}
}
if (mark==1) continue;
if (maxn>minn) { // 要求maxn>minn,即满足条件maxn < x < minn,才有结果输出,否则输出-1
cout << -1 << endl;
continue;
} else {
cout << maxn << endl;
}
}
return 0;
}
【运行结果】
6
1
10
1
0
0
2
7 3
8 10
1 0
3
2
3 6
10 8
0 1
2
2
7 3
8 9
1 0
5
2
7 7
8 8
0 1
-1
2
7 3
8 8
1 0
-1
浙公网安备 33010602011771号