前言:哎,这场打的就很nanshou,开局a出俩题,剩下的数学题兴趣就直接无了,结果俩小时直接结束战斗。
结束之后看了一下题解,感觉D题讲的有点麻烦,这边讲一下一种更低效率不过更加直观的做法。如果有看不懂题解的朋友可以尝试一下我的理解。
正文开始#
没看过题目的可以去牛客先看一下。我这里自己出一组数据。
1
5 2
3 3 2 0 2
这里介绍一个算法,差分算法,至于为什么想到的,只能说看到这题就本能的就想到这个算法。
我们对数据进行差分(就是前一个数减后一个数)。得到差分数组cut。
0 1 2 -2
然后我们从左到右推,每次遇到一个数 cut[i] 为正就让cut [ i+k ]加上cut [ i ],cut [i] = 0。注意这里的i+k必须小于等于n(这里是5)。至于为什么后面解释。
然后变成了
0 0 0 -1(2)(最后一个2是前面推来的,在位置n上,我们不需要这个数)
然后从右往左,每次遇到cut [ i ]为负数就让cut [ i - k ] += cut [ i ],cut [ i ] = 0。注意i+k>=0。
然后变成
(-1) 0 0 0 0 (2)
这里面的位置为1到4都是0,所以可以得出结果。
然后解释一下我们为什么做这种操作,我下面列一些变化过程。
3 3 2 0 2 cut:0 1 2 -2
3 3 3 1 2 cut:0 0 2 -1
3 3 3 3 4 cut:0 0 0 -1 (2)
3 3 4 4 4 cut:0 -1 0 0 (2)
4 4 4 4 4 cut:(-1) 0 0 0 0 (2)
懂了吧?因为一次操作的区间为k,所以差分数组会变化的只有i和i+k或i和i-k。
假如i+k>n或者i-k<0,则是不可能的,我们也举个例子。
k=2,3 4 4 4 4 , cut:-1 0 0 0
我们就无法把这个-1给清除掉,因为这涉及数组外的数了。
下面给出代码,速度还有很大的空间可以优化,但是没必要
//
// Created by acer on 2021/2/21.
//
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5 + 10;
int num[maxn];
int cut[maxn];
signed main() {
int</