差分與字首和——一種技巧
阿新 • • 發佈:2019-02-13
字首和的概念相信很多人都知道.
就是一個數組,要快速靜態查詢區間和,我們只要處理一個數組時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)查詢.