原题链接:https://ac.nowcoder.com/acm/contest/73854/E
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
大白熊给了小苯一个长度为 n 的数组 a,他希望小苯将数组 a 变成有序(非递减)的。具体的,小苯需要进行如下操作:
1.任选一个数组 b,长度也为 n,且元素满足:−10^10≤bi≤10^10
2. 对于所有 1≤i≤n,都执行 ai=ai+bi
大白熊希望在执行完操作后 a 数组满足有序,同时要最小化数组 b 的极差,即使得:max(b1,b2,...,bn)−min(b1,b2,...,bn)最小 。
请你帮小苯找出一个合法的 b 数组吧。
注:如有多解输出任意即可。
输入描述:
输入包含两行。 第一行一个正整数 n(1≤n≤2×105),表示 a 的长度。 第二行 n 个整数 ai(−10^9≤ai≤10^9),表示数组 a 的元素。
输出描述:
输出包含一行 n 个整数,表示构造出的 b 数组(有多解输出任意即可)。
如果找不到合法的 b 数组,请输出一个整数 −1。
示例1
输入
2 1 2
输出
114514 114514
说明
可以构造 b=[114514,114514],这样 b 的极差为 0,可以证明不存在比 0 更小的极差。
备注:
数组的极差 = 数组中的最大值减去最小值。
解题思路:
首先我们不考虑b数组极差的限制,我们可以增大b数组相邻元素的差值,从而减少a数组对ai+bi的影响,也就是说我们可以增大b数组的极差使得ai=ai+bi之后新的a数组变成有序的,也就是说答案越大就越有可能使得a数组单调不减,答案是具有单调性的。
然后我们知道让数组b整体加某个数或者减某个数是不影响答案的,我们不妨固定b[1]=0,也就是说ai的第一个数是不变的,那么要使得后面单调不减,那么当前位置ai>=aj(0<=j<=i),如果当前位置比以当前位置结尾的前缀最大值小,那么当前这个数至少要变为前缀最大值,如果当前这个位置等于以当前位置结尾的前缀最大值,那么当前位置也至少要等于前缀最大值,当然当前位置也可以大于前缀最大值,但是大于前缀最大值会让极差变大,同时会导致后面的极差也变大,所以我们让每个位置ai都等于a数组的以当前位置i结尾的前缀最大值就是答案,这种情况就是极差最小的情况。
时间复杂度:直接枚举一遍的同时记录前缀最大值,所以时间为O(n)。
空间复杂度:O(n)。
cpp代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>using namespace std;
typedef long long LL;
typedef pair<int, int> PII;const int N = 2e5 + 10;
int n, m;
int a[N];
LL b[N];
LL ans[N];
int main()
{cin>>n;for(int i=1;i<=n;i++)scanf("%d",&a[i]);LL pre_max=-1e9-10;for(int i=1;i<=n;i++){pre_max=max(pre_max,(LL)a[i]);ans[i]=pre_max-a[i];}for(int i=1;i<=n;i++)cout<<ans[i]<<' ';return 0;
}