用途:主要用于给某一区间 加一个数,或减一个数 。o(1)的时间内完成

差分,实际上就是前缀和的逆过程, 例如 已知前缀和数组 b, 那么它的差分数组 a

a1 = b1;

a2 = b2-b1;

a3 = b3-b2;

a4 = b4-b3;

an= bn-bn-1;

如果把它们相加就很容易看出: a1+a2+a3+a4+…an = bn;

题目:
给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。

求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。

1、此题说每次在某一个区间【L,R】内加一或减一,如果暴力做的话时间复杂度是o(n)的,所以我们可以先离线出a数组的差分数组b
2、此题要是数组a一致,就是使数组a的差分数组b除了b【1】其他都为0::数组b为:b1,0,0,0,······
2、对差分数组b的操作有4种:

	1    	2<=i,j<=n;
	2      	i=1,j<=n;
	3   	2<=i<=n,j=n+1;
	4   	i=1,j=n+1

所以我们可以用贪心的思想,来使得b中所有数变成零。 我们知道我们在做 b[L]++, b[R+1]–;操作的时候,要找两个数配对,那么 负数++,正数–,是不是就最快了。 但是最终结果可能依然不是全 0 的,因为 abs(sum(正数)) 可能 != abs(sum(负数))

所以,我们可以 让最后不等于0 的数全和 b1|| bn+1 来换==进行2.3操作(2,3操作的代价为+或-1)

所以 ans1 = min(pos,neg)+abs(pos-neg);
ans2 = abs(pos-neg)+1; /// 最后的序列有多少种,即b【1】的值有多少种,b【1】的值由操作2决定,即b【1】的值可能数为:abs(pos-neg)+1;

 posted on 2019-07-08 20:57  谁是凶手1703  阅读(116)  评论(0)    收藏  举报