1. 程式人生 > >差分與字首和——一種技巧

差分與字首和——一種技巧

字首和的概念相信很多人都知道.

就是一個數組,要快速靜態查詢區間和,我們只要處理一個數組時A[i]=a[1]+a[2]+...+a[i].

那麼查詢區間[l,r]的時候只要輸出A[r]-A[l-1].

那麼這是時候預處理是O(n)的,查詢一次是O(1).

在很多情況下這種演算法都是可行的,但是必須滿足區間減法的性質.

程式碼預處理如下:

for (int i=1;i<=n;i++)
  A[i]=A[i-1]+a[i];

那麼差分又是另一種概念.

只不過它可以配套字首和使用.

差分是一種很巧妙的思想,它的主要用途是維護一個區間的快速修改(加減),但查詢是單次的時候.

這種思想的主體就是維護一個數組A,其中A[i]=原陣列a[i]-a[i-1].

那麼就是剛好與字首和有點像.

也是互逆的運算.

那麼這怎麼快速維護呢?

也就是說給區間[l,r]+num.

那麼就是給開頭A[l]+num,再給結尾A[r+1]-num.

很好理解啊.

那麼實現如下:

void add(int l,int r,int num){
  A[l]+=num;A[r+1]-=num;
}

那麼最後需要查詢了,就這樣處理一下:

for (int i=1;i<=n;i++)
  a[i]=a[i-1]+A[i];

那麼就是原來的陣列了.

時間複雜度O(1)修改,O(n)查詢.