字首和 差分之我見

2021-09-25 06:18:43 字數 1315 閱讀 7153

字首和

顧名思義:前n項和。

一般情況下,如果給出一串長度為n的a1,a2,a3…an,再給出m個詢問,每次詢問給出l,r兩個數,要求給出區間[l,r]裡的數的和。如果暴力的話,肯定會超時。但我們如果去用字首和去計算的話(先分別求出前i項和,後面求a[r]-a[l-1]就可以得到我們要求的答案了),時間複雜度會降到o(n+m)。

差分

首先,給出乙個問題:

給出n個數,再給出q個詢問,每個詢問給出le,ri,x,要求你在le到ri上每乙個值都加上x,而只給你o(n)的時間範圍,怎麼辦?

思考一下:

如果暴力,卡一下le和ri,隨隨便便讓你o(n^2)t成狗。

用線段樹或樹狀陣列搞一搞,抱歉,這個複雜度是o(qlogn)的,還是會t(雖然他們解決別的題目很nb)

差分,沒錯,就是標題,很高興o(n)+常數…(思想:在詢問中我們不去for來加x,而是做乙個標記,最後一起加上。)

實現方法:

先另外開乙個專門差分的陣列(大小=題中的序列長度

假如在3~8的區間上加上5,那我們在差分陣列中的3位置上加上乙個5(原因暫時不懂沒關係,用筆先跟著模擬),再在8+1的位置上減乙個5,如此操作完q次。

假如我們只有這一次操作,開始統計答案,運用前置和的思想,那麼你會發現(如果你模擬了的話),在3~8的區間上,你已經使差分陣列全部加上了5(推廣到所有q一起統計答案依舊正確)

再用o(n)的for把他們加到原序列之中去,輸出!

看一下複雜度,果然:o(常數*n).

**實現:

#include 

int main()

; int chafen[

100]=;

int i=

1,q,le,ri,x,j,add=

0,a,b;

while

(scanf

("%d"

,&num[i])!=

eof)

printf

("請輸入進行幾次操作:");

scanf

("%d"

,&q)

;while

(q--

)for

(j=1

;j)printf

("請輸入查詢區間的和:");

scanf

("%d%d"

,&a,

&b);

printf

("%d"

,num[b]

-num[a-1]

);return0;

}

字首和 差分

數列的字首和 sum i 表示a 1 a i 的和 用處1 求i j的和sum j sum i 1 用處2 區間修改。設定乙個change陣列。當區間 i,j 上要加k時,我們令change i k,令change j 1 k。如果我們對change陣列求字首和的話,字首和sum change i ...

字首和 差分

有n個數和q次操作,每一次操作指明了要操作的區間 l,r 以及讓該區間內的所有元素全部加c 輸出q次操作後所有元素的大小 第一行 n q 1 n,q 2 105 第二行 n個數 a1,a2 an 106 ai 106 接下來q 行 每行3個數 l r c 表示 l,r 區間內每個數加c 1 l r ...

字首和 差分

顧名思義 用某乙個陣列來記錄陣列a前i項和,這個還可以用來求區間 l,r 的和 s r s l 1 因為第l項也在區間內 話不多說,直接上例題 leetcode 5393 ac const int maxn 1e5 5 class solution int ans 0 for int i 0 i k...