牛客小白月赛87 E.小苯的数组构造【构造+贪心】

原题链接: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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值