G - FacePalm Accounting Gym - 100513G

An owner of a small company FacePalm has recently learned that the city authorities plan to offer to small businesses to participate in improving parks and garden squares. However, credible sources informed the FacePalm owner that the loss-making companies will not get such an offer. Moreover, the sources have also told how loss-making companies will be determined.

A company will be considered loss-making if for every k contiguous days the total income of the company is negative.

The FacePalm owner discussed the situation with his chief accountant, and they decided to change the report so that the company would look loss-making.

The company report for n days can be represented as a sequence of integers a 1, a 2, …, a n, where a i is the company income in the day i (negative values correspond to losses).

The accountant can change any values in this sequence, but no updated value can become less than the smallest value in the original report — otherwise the updated report will look absolutely implausible. Besides, the accountant wants the total change of the values to be as small as possible.

We will assume that the total change of the values is , where is the i-th value in the updated report.

Your task is to calculate the minimum required total change of the values and provide the updated report.

Input
The first line contains integers n and k (1 ≤ k ≤ n ≤ 2·105) — the number of days in the report and the number of days in the definition of loss-making company.

The second line contains n space-separated integers a 1, a 2, …, a n ( - 10000 ≤ a i ≤ 10000), where a i is the company income in day i.

It is guaranteed that at least one value of a i is negative.

Output
In the first line print the required minimum total change. In the second line print the corresponding updated report. No value in the updated report can be less than the minimum value of the original report.

扫描二维码关注公众号,回复: 11188005 查看本文章

If there are multiple solutions, print any of them.

Examples
Input
5 4
3 -3 -1 1 2
Output
1
2 -3 -1 1 2
Input
8 3
2 1 -3 -2 4 -3 0 2
Output
3
1 1 -3 -2 2 -3 0 2
Input
4 2
-2 1 -2 1
Output
0
-2 1 -2 1
Input
3 3
-5 6 10
Output
12
-5 -5 9
Sponsor

题意:
你可以修改原序列的数,但是要求修改后的序列,最小值不小于原序列。求最少修改值使得任意k个连续数的和都是负数。

思路:
维护一个长度为k的”滑动窗口“,从第k个数开始修改,直到这k个数和小于0。然后右移窗口。

复杂度证明:
到了第m个窗口(m > 1)

  • 假设第m-1个窗口的第一个值是正数,这个数会被删掉,剩余m-1个数和为负数,而第m窗口最后一个数可以修改成负数,所以最多修改一次。
  • 假设第m-1个窗口的第一个值是负数x,那么剩余m-1个数的至多为 -x-1,同理可以把第m个窗口最后一个数修改成-x,所以最多修改一次

所以除了第一个窗口,其他窗口最多修改一次,复杂度是O(n)。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <string>
#include <iostream>
using namespace std;

typedef long long ll;
const int maxn = 2e5 + 7;

int a[maxn];

int main() {
    int n,k;scanf("%d%d",&n,&k);
    int mi = 0;
    for(int i = 1;i <= n;i++) {
        scanf("%d",&a[i]);
        mi = min(mi,a[i]);
    }
    int now = 0,ans = 0;
    for(int i = 1;i < k;i++) now += a[i];
    
    for(int i = 1;i <= n - k + 1;i++) {
        now -= a[i - 1];
        now += a[i + k - 1];
        if(now >= 0) {
            for(int j = i + k - 1;j >= i;j--) {
                int num = min(a[j] - mi,now + 1);
                a[j] -= num;
                now -= num;
                ans += num;
                if(now < 0) break;
            }
        }
    }
    
    printf("%d\n",ans);
    for(int i = 1;i <= n;i++) {
        printf("%d ",a[i]);
    }
    return 0;
}
原创文章 930 获赞 38 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/106057050