《淺談函數最值的動態維護》 - 學習筆記


EI 隊長不務正業

又是一個(對於我來說)理性愉悅的東西,大概幾年之內(或者這輩子?)都不會寫這東西的代碼……

1 概述

自然的想法是維護這些函數取 \(\max\) 之后得到的分段函數,但這就帶來一個問題:分段函數最多能分多少段。

只考慮任意兩個函數,如果段數不超過 \(s+1\) ,那么總的分段函數的段數也會有一個比較緊的界。

考慮分段函數每一段屬於哪個函數,設為 \(\{a_i\}_{i=0}^m\) 。如果存在 \(x,y\) 使得 \(a\) 中存在長度超過 \(s+1\)\(x,y\) 交替子序列,那就與 \(\max(f_x,f_y)\) 段數不超過 \(s+1\) 矛盾。

於是引入

1.1 Davenport-Schinzel 序列

那么段數的上界就和 \(DS(n,s)\) 的長度有關。

有一個牛逼定理:

於是我們驚喜地發現,段數竟然幾乎是線性的。

1.2 DS 序列與問題的聯系

為什么 \(s\) 次分段函數的階是 \(s+2\) 呢?如果定義域無交那么顯然只有 2(還是 3 ?)段,否則可能在兩者的定義域中已經獲得了 \(s\) 個交點,而在邊界還會獲得兩個。

2 函數集合維護

有了上面那個結論之后這里顯得比較簡單。

如果函數初始給定,那么直接分治合並所有函數,然后詢問的時候二分 \(x\) 在哪一段即可(當然如果可以離線就沒必要二分了)。預處理復雜度 \(O(\lambda_s(n)\log n)\) ,詢問復雜度 \(O(m\log n)\)

如果是一邊添加函數一邊詢問:用經典的二進制分組算法(也就是不完全的分治)處理修改,但詢問要在 \(O(\log n)\) 個分段函數上二分,復雜度變為 \(O(m\log^2 n)\)

但是容易發現可以用分散層疊來優化二分的過程,在新合並出一個 \(2^k\) 的段時把 \(2^{k},2^{k-1},\cdots,1\) 的分散層疊重構,而重構的復雜度並不是瓶頸。於是復雜度仍然是 \(O(m\log n)\)

2.3 應用

2.3.1 維護分段一次函數最值

直接做就行了。

2.3.2 動態規划問題

\[a_i=\max_{0\le j<i} a_j+w_{j,i} \]

\(f_j(x_i)=a_j+w_{j,i}\) ,如果 \(f_j,f_k\) 交替階數較低,那就可能可以大力維護分段函數。

通常有兩類做法:直接發現 \(f_j\) 是關於 \(x_i\) 的一次函數,或者發現有決策單調性。

如果是一次函數那就直接做,否則決策單調性一般會滿足四邊形不等式,就有

也就是 \(f_{i+1}-f_i\) 單調遞增,所以 \(\max(f_i,f_{i+1})\)\((i+1,n]\) 上階為 1 ,所以 \(i<i_0\) 的函數取 \(\max\)\([i_0,n]\) 上是 \(s=1\) 階交替。

怎么求分段點就是另外一回事了……?

3 詢問點單調遞增

3.1 Kinetic Tournament 樹

用線段樹維護區間中對於當前 \(x\) 取到最大值的函數是哪個,而 \(x\) 變化的時候暴力修改。

每個點的分段個數是 \(\lambda_s(n)\) ,再帶上 \(\log n\) 層,再加上修改的時候是暴力從根節點往下 dfs 修改,所以復雜度 \(O(\lambda_s(n)\log^2 n+q)\)

3.2 帶修改函數序列最值問題

現在可以支持單點修改函數序列。

由於 \(x\) 單調遞增,所以一個位置仍然可以看做只有一個函數,只不過這個函數分段。於是復雜度變為 \(O(\lambda_{s+2}(n+m)\log^2 n+q)\)

實現的時候當然沒有必要關心函數具體怎么分段,修改的時候暴力即可(吧)。所以該在線還是在線。

4 線性情況的擴展

一次函數比較優美,因為如果只有 \(x\) 單調遞增的話那么一定是從斜率較小的函數切換為斜率較大的函數。

4.1 包含兩類區間修改的序列最值問題

另外還要求 \(x>0\) 。為了方便,再加上 \(k_i,b_i,c>0\)

類似於每個位置有一個函數 \(k_ix+b_i\) ,一操作讓區間的 \(x\) 增加,二操作看起來比較迷惑,但是被二操作完全覆蓋的區間中 \(k,b\) 的大小關系都沒有變化,並且好像可以看做 \(x\) 也沒有變化?

考慮 \(k_1x+b_1\)\(k_2x+b_2\) ,且 \(b_1>b_2,k_1<k_2\) ,在同時經過二操作之后會發生什么。原來是還需要 \(x\) 增加 \({b_1-b_2\over k_2-k_1}\) 才會使得大小關系改變,而現在竟然完全沒有變化。

於是有這么一個做法:線段樹維護區間的 \(x,k,b\) 發生了什么變化,以及最大值在哪里取到,以及 \(x\) 再整體增加多少就會使得最大值切換。

一操作時如果沒有切換最大值那就無事發生,否則遞歸下去換;二操作一定不會切換最大值,也不會改變“還要多久才切換”。而 pushup 是簡單的。

唯一的問題是一操作中的“遞歸下去換”,這個復雜度是什么。

4.1.1 復雜度分析

如前所說,切換最大值的時候一定是從斜率小的換成斜率大的。

那么一次對 \(v\) 的切換會使得 \(\Phi\) 減小 \(d(v)\) ,但同時又可能增加 \(d(fa_v)\) ,所以至少減小 1 。

兩種操作會帶來什么呢?只有被碰到的節點可能會被丟進 \(\mathcal {P}\) 中,只會碰到 \(O(\log n)\) 個點,所以只會增加 \(O(\log^2 n)\) 的勢能。

初始還有 \(O(n\log n)\) 的勢能。

所以總復雜度 \(O(n\log^2 n+m\log^3 n+q\log n)\)

4.1.2 特殊情況

“區間增加公差為正的等差數列”,即保證 \(k_i\) 單調遞增。

那么切換就只能從左兒子切換到右兒子。另外,對於 \(x\) ,如果它子樹中的 \(\max\) 已經在右兒子了,那么打 \(tag\) 的時候即使 \(ls\) 被切換了, \(x\) 也不會被切換,因為右邊加的比左邊多。

所以可以直接設 \(\Phi\) 為“\(\max\) 位於左子樹”的點數,比上面少一個 \(\log\) ,復雜度 \(O(n\log n+m\log^2 n+q\log n)\)

4.2 例題

於是獲得了好多個 $\log $(

亂做?

4.2.1 最大連續子段和

區間加正數,區間最大子段和。

於是要維護 \(sum,lmax,rmax,totmax\) 。它們滿足

全都是關於區間加的一次函數。

如何構造一個神奇的勢函數,使得切換一定會消耗勢能呢?顯然還是應該和“斜率比自己選的直線的斜率大的個數”有關。要考慮到給自己切換的時候可能也會影響父親。

\(lmax\) 切換,可能會使得自己的斜率比父親的 \(lmax,totmax\) 大; \(rmax\) 同理;\(totmax\) 則只會使得自己的斜率比父親的 \(totmax\) 大。所以要求 \(l_d>l_{d-1}+t_{d-1},r\cdots,t_d>t_{d-1}\) 。於是可以令 \(t_d=d,l_d={d(d-1)\over 2}\)

初始勢能:給 \(lmax\) 的勢能貢獻 \(O(n\log^2 n)\) ,給 \(totmax\) 的勢能貢獻 \(O(n\log n)\)

一次修改:給 \(lmax\) 的勢能貢獻 \(O(\log^3 n)\) ,給 \(totmax\) 的勢能貢獻 \(O(\log^2 n)\)

於是分析出了復雜度 \(O(n\log^3 n+m\log^4 n+q\log n)\) (切換一次還會乘上額外的 \(O(\log n)\) )。

不過注意到 \(lmax\) 的轉移點一定是單調地從左往右,所以 \(lmax,rmax\)切換次數其實僅僅是 \(O(n\log n)\) ,貢獻到 \(totmax\) 的勢能上就是 \(O(n\log^2 n)\) ,然后再把 \(totmax\) 的復雜度分析抄過來,就得到 \(O((n+m)\log^3 n+q\log n)\)

看着還行

如果沒有“轉移點單調往右”的性質那就只能用上面那個復雜度分析了。

4.2.2 henry_y 的數列

逐漸陰間。

區間加二次函數?換成把 \(i,i^2\) 看做系數, \((a,b)\) 看做變量。因為 \(i,i^2\) 單調遞增,而 \(a,b\ge 0\) ,所以區間打 \(tag\) 時最小值位置一定是從右往左走。

什么時候會切換呢?假設左子樹 \(\min\)\(A_i\) ,右子樹在 \(A_j\) ,且 \(A_j<A_i\) ,那么

\[A_i+ai^2+bi\le A_j+aj^2+bj\\ {A_i-A_j\over j-i}\le a(i+j)+b \]

\((a,b)\) 走到某個半平面內的時候才會切換。

這就比較麻煩了,切換的條件從一維變成二維的了。

頭鐵,直接維護子樹中的半平面交。注意到直線斜率 \(i+j\) 滿足 \(ls< x< rs\) ,所以可以直接可持久化平衡樹維護半平面交,合並的時候二分。

另外,仍然注意到右邊加的比左邊多,所以可以令 \(\Phi\) 為 “\(\min\) 在右子樹取到的點數” ,省一個 $\log $ (?)

復雜度 \(O((n+m\log n)\log^2 n+q\log n)\)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM