字首和 差分與樹上差分

2021-09-11 22:17:59 字數 2293 閱讀 2353

1.1 字首和:字首和可以通過對乙個序列進行o(n)的預處理後,在o(1)時間內求出任意乙個子串行的和。

1.2 差分:可以用於求解多次區間修改與區間詢問的題型,例如多次次給[ l , r ] 內所有數 + val,就可以用差分以及字首和來優化。區間操作o(1),區間詢問o(n)處理,o(1)查詢。

1.3 樹上差分:同樣的,如果我們有若干次操作與若干次詢問,每次操作對從u 到 v 路徑上所有節點加乙個值,那麼我們用樹上差分可以將時間複雜度控制在o(1)上,詢問同樣是o(n)處理,o(1)查詢。

2.1 問題描述:給出一串長度為 n 的數列a1,a2,a3......an,再給出m個詢問,每次詢問給出l,r兩個數,要求給出區間[l,r]裡的數的和。

2.2 樸素思路:最簡單的做法就是設定乙個變數sum,將所有處在區間內的數累加到 sum 上,最後輸出sum的值即為答案。但是這樣的時間複雜度為o(nm),難以接受。

2.3 字首和:假設我們開乙個陣列sum,sum[ i ]存放數列中前 i 個元素的和,即

3.1 問題描述:給出一串長度為 n 的數列a1,a2,a3......an ,給出k次操作,每次操作給出l、r、val,要求對[l , r]內所有元素加上val,再給出m個詢問,每次詢問給出l,r兩個數,要求給出區間[l,r]裡的數的和。

3.2 樸素思路:很容易想到的做法就是每次給出l r 和 val後,我們就挨個對[ l, r ] 內所有元素+val,再在詢問時將答案挨個加起來。這樣時間複雜度為o(kmn),不能接受。

3.3 差分:

既然之前我們可以用字首和來進行優化,這裡我們是否也可以用字首和試著優化呢?

假設 sum 陣列初始值全是為 0 ,如果我們要將 [ l , r ] 上所有元素 + val,那麼我們設sum[ l ] = val,sum[ r ] = -val。這樣一來當我們詢問時,我們對sum陣列進行一次更新,即sum[ i ] = sum[ i - 1 ] + ai;那麼此時的sum陣列就是在進行 k 次操作後的陣列的字首和陣列。

根據2.3我們可知,這樣查詢的效率為o(1),於是時間複雜度就成了o(k+n)。

4.1 問題描述:

4.2 樸素思路:不用多想,最暴力的做法就是我們找到 u 到 v 路徑上的所有點並+1(可以利用lca)。最後再遍歷所有點查詢權值最大的點並輸出。這樣時間複雜度為o(kn),這還不包括 lca 查詢路徑的時間。

4.3 求u到v的路徑:求那麼我們知道,如果假設我們要考慮的是從u到v的路徑,u 與 v 的 lca 是 a ,那麼很明顯,如果路徑中有一點 u′ 已經被訪問了,且 u′ ≠ a ,那麼 u' 的父親也一定會被訪問。所以,我們可以將路徑拆分成兩條鏈,u -> a 和 a -> v。

4.4 樹上差分:常見的樹上差分有兩種形式,即

4.4.1 關於邊的差分:

將邊拆成兩條鏈之後,我們便可以像差分一樣來找到路徑了。用 cf[ i ] 代表從i到i的父親這一條路徑經過的次數。因為關於邊的差分,a 是不在其中的,所以考慮鏈 u -> a,則就要使cf[ u ]++,cf[ a ]−−。然後鏈a -> v,也是cf[ v ]++,cf[ a ]−−。所以合起來便是cf[ u ]++,cf[ v ]++,cf[ a ]−=2。然後,從根節點,對於每乙個節點x,都有如下的步驟:

(1)列舉x的所有子節點u

(2)dfs所有子節點u

(3)cf[ x ] + = cf[ u ]

那麼,為什麼能夠保證這樣所有的邊都能夠遍歷到呢?因為我們剛剛已經說了,如果路徑中有一點u′已經被訪問了,且u′≠a,那麼u′的父親也一定會被訪問。所以u′被訪問幾次,它的父親也就因為u′被訪問了幾次。所以就能夠找出所有被訪問的邊與訪問的次數了。路徑求交等一系列問題就是通過這個來解決的。因為每個點都只會遍歷一次,所以其時間複雜度為θ(n).

4.4.2 關於點的差分:

還是與和邊的差分一樣,對於所要求的路徑,拆分成兩條鏈。步驟也和上面一樣,但是也有一些不同,因為關於點,u與v的lca是需要包括進去的,所以要把lca包括在某一條鏈中,用cf[ i ] 表示 i 被訪問的次數。最後對 cf 陣列的操作便是cf[ u ]++,cf[v]++,cf[ a ]−−,cf[ father[a] ]−−。其時間複雜度也是一樣的θ(n).

暖 墟 差分 字首和與差分

即 用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...

字首和與差分

數列的字首和 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 ...

字首和與差分

從陣列第乙個開始累加 s i s i 1 a i 求區間 l,r 的和,o 1 複雜度sum s r s l 1 遞推s i j s i j s i 1 j s i j 1 s i 1 j 1 例題 雷射炸彈一種新型的雷射炸彈,可以摧毀乙個邊長為r的正方形內的所有的目標。現在地圖上有n n 1000...