Github IO

每日一题——差分数组

2021/02/18

朴素思想

从左到右翻转,遇到0,将随后的值翻转为1
纯粹模拟的问题:

  1. 重复翻转,每次检测一个数时间复杂度O(N),每检测一次翻转K个,总体时间复杂度O(KN)

提炼:

  1. 翻转次数的计算核心:检测一个项在经历了前面的反转后是否仍需要翻转(仍为0)。是,翻转次数加一,否则跳过。
  2. 每个点上的翻转次数:被翻转多一次,状态就在两种状态间转移一次,翻转次数的奇偶性也在两种状态间转移一次。所以可以用翻转次数奇偶性来表述实际值的两种状态。

进一步:我们只需要知道在检测一个项时,他到底被翻转了多少次,后面反转了多少次暂时不需要被确定。
也就是说只要我们知道:

  1. 翻转次数的起点 revCnt[0] = 0
  2. 每次的差分值 diff[i]
  3. 就能累积出每次的翻转次数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
posted @ 2021-02-18 15:01  laiyk  阅读(49)  评论(0)    收藏  举报