1. 程式人生 > 其它 >「tricks」平凡二分幻術

「tricks」平凡二分幻術

其實這個的標題叫 平凡線段樹上二分幻術,因為這是一個民科在亂叫。

如標題所言,這個東西確實非常 trivial。礙於網路上沒有一個成體系的文章供參考就只能自己來炒炒冷飯。

如果出了什麼 bug 就當個笑話看。


我們這樣來描述一類問題

給出一個序列 \(\{a_n\}\) 以及函式 \(\textbf{f}(x)\in\{0,1\}\),在 \([l,r]\) 中查詢滿足 \(\textbf{f}(a_i)=1\) 的所有位置所組成的集合中的一個元素,該元素滿足某個指定的性質。

網路上大部分資料對這類問題的線段樹二分做法只停留在全域性查詢。事實上,線段樹二分的做法完全可以搬到區間上,做法並不困難。

以下令 \([l,r]\) 為線段樹執行時的當前區間,\([x,y]\) 為詢問區間。

我們在執行線段樹的時候,維護一個標記 \(g\in\{0,1\}=[[l,r]\subseteq[x,y]]\),如果為 \(0\),則繼續線上段樹上搜尋詢問區間,否則就執行二分,因為查詢的結點數為 \(\Theta(\log_2 n)\) 且樹的深度為 \(\Theta(\log_2 n)\),所以單次複雜度 \(\Theta(\log_2 n)\)


例題大概是 codeforces - 407E,我負責給李涵口胡,然後李涵就把程式碼槓出來了。

順便這個東西其實不是不普及,只是網路上的文章都出奇的統一線上段樹二分層面上只寫全域性查詢,真是個奇怪的現象。