每日一题——差分数组
朴素思想
从左到右翻转,遇到0,将随后的值翻转为1
纯粹模拟的问题:
- 重复翻转,每次检测一个数时间复杂度O(N),每检测一次翻转K个,总体时间复杂度O(KN)
提炼:
- 翻转次数的计算核心:检测一个项在经历了前面的反转后是否仍需要翻转(仍为0)。是,翻转次数加一,否则跳过。
- 每个点上的翻转次数:被翻转多一次,状态就在两种状态间转移一次,翻转次数的奇偶性也在两种状态间转移一次。所以可以用翻转次数奇偶性来表述实际值的两种状态。
进一步:我们只需要知道在检测一个项时,他到底被翻转了多少次,后面反转了多少次暂时不需要被确定。
也就是说只要我们知道:
- 翻转次数的起点 revCnt[0] = 0
- 每次的差分值 diff[i]
- 就能累积出每次的翻转次数revCnt[i]
状态转移核心伪代码:
for i in (1, size):
revCnt[i] = revCnt[i-1] + diff[i] # A[i]已被翻转的次数
if((A[i] + revCnt) % 2 == 0) # A[i]的现态, 若A[i]还需要被翻转则
diff[i] += 1; # 翻转[l, r],翻转次数只有 l 比 l-1 多1
diff[i + K] -= 1; # r+1 比 r 少1

浙公网安备 33010602011771号