P3374 模板 樹狀陣列 1 題解

2021-10-07 13:26:30 字數 2474 閱讀 2423

同步

原題鏈結

給定乙個長度為 n

nn 的陣列,q

qq 組操作:

顯然,假設你現在什麼也不會。

我們只考慮第 2

22 個操作,即先不考慮修改,如何處理區間和的詢問?

顯然,對於初始的陣列 a

ia_i

ai​,只需要做乙個字首和 s

ss 使得:

s j=

∑i=1

ja

is_j = \sum_^j a_i

sj​=i=

1∑j​

ai​

這樣,對於一組詢問:

∑ i=

lrai

=sr−

sl−1

\sum_^r a_i = s_r - s_

i=l∑r​

ai​=

sr​−

sl−1

​ 可以做到 o(n

)−o(

1)

\mathcal(n) - \mathcal(1)

o(n)−o

(1).

但是現在出題人加入了修改操作,你再修改的時候不得不把 s

ss 重推一遍。

這樣 o(n

)−o(

n)

\mathcal(n) - \mathcal(n)

o(n)−o

(n) 我們就完了啊。

從字首和上我們可以考慮,如何用較少的字首和記錄較多的區間答案

乙個合法的思路是利用 rmq

\text

rmq,記:

f x,

y=∑i

=x

min⁡(x

+2y−

1,n)

ai

f_ = \sum_^ a_i

fx,y​=

i=x∑

min(x+

2y−1

,n)​

ai​

然後可以做到 o(n

log⁡n)

−o(1

)\mathcal(n \log n) - \mathcal(1)

o(nlogn)

−o(1

).但是我們覺得這不好,我們用部分字首和。

即我們只記錄一部分的字首和,查詢時查詢較少一部分,修改時也只要修改較少一部分,達到複雜度的均衡。

因此,我們想到了用 lowbit

\text

lowbit

表示字首的長度。你可以理解為每次 +

++ 或 −

-− 乙個 lowbit

\text

lowbit

會在原數的二進位制中砍掉一位。

這樣,我們就可以做到 o(n

log⁡n)

−o

(log⁡n

)\mathcal(n \log n) - \mathcal(\log n)

o(nlogn)

−o(logn)

.這就是樹狀陣列。其實樹狀陣列的本質就是用部分字首和維護差分陣列

時間複雜度:o(n

log⁡n)

−o

(log⁡n

)\mathcal(n \log n) - \mathcal(\log n)

o(nlogn)

−o(logn)

.實際得分:100pt

s100pts

100pts

#pragma gcc optimize(2)

#include

using

namespace std;

const

int n=

1e6+1;

typedef

long

long ll;

inline

intread()

int x=0;

while

(ch>=

'0'&& ch<=

'9') x=

(x<<3)

+(x<<1)

+ch-

'0',ch=

getchar()

;return x*f;

}int a[n]

; ll c[n]

;int n,m,x,y;

inline

intlowbit

(int x)

return x &

(-x);}

inline ll sum

(int x)

return s;

}inline

void

update

(int x,

int k)

}int

main()

while

(m--

)return0;

}

題解 P3374 模板 樹狀陣列 1

最簡單的zkw線段樹就十分適合這道題,為什麼用zkw線段樹,可以看一下以下精簡 我們只需要用到單點修改,區間查詢就好了。include define go i,j,n,k for int i j i n i k define fo i,j,n,k for int i j i n i k define...

題解 P3374 模板 樹狀陣列 1

恩,這是ac的第一道樹狀陣列呢。如今終於找到了折中方案 樹狀陣列!量小,還支援修改!樹狀陣列也就是二叉索引樹,又被稱為fenwick樹,然而我個人認為它不能被嚴謹地成為樹,因為充其量只是借用的樹形結構的思想,於實現上有著較大的區別。樹狀陣列雖然運用範圍沒有線段樹那麼廣,但是它的效率要高很多,比如線段...

P3374 模板 樹狀陣列 1

如題,已知乙個數列,你需要進行下面兩種操作 1.將某乙個數加上x 2.求出某區間每乙個數的和 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含3個整數,表示乙個操作,具體如下 操作1 ...