题意
给定长度为n的非递减数组a,1<=a[i]<=1e9, a[i]<=a[i+1]
定义数组b,b[i]=a[i]+d[i], 0<=d[i]
现给定数组a,b。
求d数组在每个位置能取到的最大、最小值。
每个位置的最大值、最小值,不同位置的最大值、最小值都是相互独立的,即它们可以对应不同的d数组。
题目输入保证有解。即至少存在一组d,使得b[i]=a[i]+d[i], 0<=d[i]
思路
对于最小值,则直接取b数组中第一个大于等于a[i]的即可。
对于最大值,考虑取尽量最大的。要保证i+1,i+2,…,n这些位置都已经用最小的b元素填充了。
详见代码。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
int n, m;
int a[maxn], b[maxn];
int mn[maxn], mx[maxn];
void solve() {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 0; i < n; ++i) {
scanf("%d", &b[i]);
}
// 直接取b数组中第一个大于等于a[i]的即可。
for (int i = 0; i < n; ++i) {
int pos = lower_bound(b, b + n, a[i]) - b;
mn[i] = b[pos] - a[i];
}
// 求最大值
multiset<int> st(b, b + n);
for (int i = n - 1; i >= 0; --i) {
// 取当前最大值
mx[i] = *(--st.end()) - a[i];
// 求i-1的最大值,要先去掉 i, ..., n的最小适配的b元素
st.erase(st.lower_bound(a[i]));
}
for (int i = 0; i < n - 1; ++i) {
printf("%d ", mn[i]);
}
printf("%d\n", mn[n-1]);
for (int i = 0; i < n - 1; ++i) {
printf("%d ", mx[i]);
}
printf("%d\n", mx[n-1]);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
}
最后
觉得文章不错子,可以weixin 搜索 对方正在debug,文章会首发到gongzhonghao上,一起快乐刷题吧~