1629. 痛苦面具

其实马家豪想让你知道这道题是有n次操作,每次操作将数组对应加上一个等差数列 例如 进行一次操作 2 6 2 那么数组变为 0 2 4 6 8 10 0 0 0... 在进行一次操作 1 5 1 数组为: 1 3 5 7 9 10 0 0 0 ...

先来说说思路了,每次操作就硬来,在数组上一一加上对应的值,思路非常清晰,接下来的n次操作也硬来。但明显会超时,因为数据已经被善良的出题人加强过了,如果你试图打表的话当我没说。 每次操作是对一个区间进行操作,那么我们想到了线段树,再仔细观察,发现这一段区间是均匀上升的,也就是后面数的减去前面的数为一个固定的常数,那么就想到了差分,每次对区间和两个端点进行修改就行了。 也有更简单的做法,就是单纯的差分两次 差分就是把前面的数全部加起来。 比如说sum的数组是(初始化为0) 0 2 2 2 2 2 0 0 0... 要修改5次 我们可以假设一个差分数组a[N],a[1]+a[2]+...+a[i]=sum[i] 也就是说sum[1]=a[1]; sum[2]=a[1]+a[2]; 那么简单求出数组a 0 2 0 0 0 0 -2 0 0 ... 只要修改两次 差分数组能够将一段要修改的序列降为单点修改 可是我们要加上的是一段上升的序列,不是一个常数 在观察一下 加上sum为 0 2 4 6 8 10 12 0 0 0... 那么差分数组a为 0 2 2 2 2 2 2 -12 0 0... 我们可以用a来求出数组sum,这时我们发现数组a中出现了一段连续的常数 我们可以再建一个差分数组b[N]来差分a 那么b就为 0 2 0 0 0 0 0 -14 12 0 ... 这样,每一次操作我们只需修改3个数就可以完成了。 即: b[Ai] += Fi; b[Bi + 1] += -(Bi - Ai + 2) Fi; b[Bi + 2] += (Bi - Ai + 1) Fi; 最后我们能将b转化为a,又能将a转化为sum求出答案