有關積分的表述只是我自己的理解,不喜勿噴。。。
一次積分需要dalta有點思考,而二次積分對dalta思考就有點麻煩了。
這個方式很直接,題目讓求什麼你就維護什麼
適用於:要改變單項而結果只是對單項積分的題目。
滑動視窗
例如:坐火車
大致的題意是給乙個n個數,求第i個數在陣列中左右兩邊相同數值的配對數之和且數值範圍在[l, r]之間,詢問可以算作i l r(題目輸入做了簡化)
如第i個數左邊a個m,右邊b個m,且m∈[l, r]那麼數值對總和的貢獻為a*b (m這個數形成了ab對組合)
而這個題目比較特殊:每個i是連續的直接暗示了你使用滑動視窗(和莫隊類似),然而我實在是太菜了,看不出來這個暗示。
n個i l r又是5e5的規模,顯然大概率與樹狀陣列或線段樹有關(然而我這個菜雞還是沒想到tvt)
在這裡樹狀陣列直接以資料值域開空間,直接維護滑動到第i個數時每個數的貢獻(不限制數值範圍),i l r就是查詢[l, r]裡的貢獻之和。而i滑動時就是對樹狀陣列的改變操作,i - 1滑動到i就表示左邊新增加num[i],右邊減少num[i],設此前左邊a個num[i],右邊b個num[i]具體到對結果改變為ab - (a+1)(b-1) = b - a,即對樹狀陣列第i位改變為b - a。(這個改變量還是要稍稍思考下的)
而維護a、b比較簡單對值域開兩個陣列即可,**是從別處學習的,就不貼了。
維護改變量是因為改變單項,但對單項一次積分只能求改變量的題目,簡而言之
適用於:要改變單項,但最終結果是對單項二次積分的題目
顯然這類題目輸入n個數字,每輸入乙個數字的過程就是對一次積分的改變,查詢到[l, r] (l和r多半是1和n)然後加到乙個sum去(二次積分)。
對單項積分就是δ,每次查詢結果就是sum + δ
例如: 牛牛的link power ii
要思考題目中將0變1或1變0的過程對sum有什麼影響,如何用數學語言表達δ。比如這一題δ = δ1 + δ2, δ1= y前面1的數量乘y - y前面所有1的位置和, δ2 = y後面1的數量乘y - y後面所有1的位置(反過來數字置)
而樹狀陣列維護1的數量和1位置即可便於求和。
未完待續…
樹狀陣列使用總結
在考試中 因為不清楚二維樹狀陣列怎麼用 而失手了無數遍了.今天終於把這個坑填了.把查詢第 x 個位置的值 s x 變為查詢字首和 s x sum x d i 其中 d x s x s 修改 l,r 的時侯,只需要修改 l 與 r 1 兩個點。查詢 1,x 則有 res sum x s x sum x...
樹狀陣列總結
樹狀陣列的基本知識已經被各種大牛和菜鳥講到爛了,我就不多說了,下面給出基本操作的 假定原陣列為a 1.n 樹狀陣列b 1.n 考慮靈活性的需要,使用int a傳陣列。define lowbit x x x int sum int a,int x void update int a,int x,int...
樹狀陣列總結
樹狀陣列是對乙個陣列改變某個元素和求和比較實用的資料結構。兩中操作都是o logn 在解題過程中,我們有時需要維護乙個陣列的字首和s i a 1 a 2 a i 但是不難發現,如果我們修改了任意乙個a i s i s i 1 s n 都會發生變化。可以說,每次修改a i 後,調整字首和s在最壞情況下...