淺談主席樹


可持久化數據結構

可持久化數據結構就是支持歷史詢問的數據結構。比如一共有\(5411\)次操作,我問你第\(251\)次操作之后這個數據結構長啥樣,你能在約束的時間空間內回答出來就算支持了可持久化,否則就不算。一種很××的做法就是每次更改構之后我都把它保存下來,然后你問哪次我就去哪次里面找就是了。但是這顯然不優秀。然后前輩們發現,每次修改只會讓該數據結構某部分與之前不同,那就只需要記錄這不同的部分就行了。

主席樹

主席樹就是可持久化線段樹,是函數式線段樹(別問我函數式是啥意思我也不知道),如果你還不會線段樹請出門左轉。對於每次修改,我們只需要把該次修改所改動的結點新建一遍,其余的結點跟上一歷史版本一樣即可。如果每次都是單點修改的話,那么就只會增加\(logn\)個新結點。由於動態開點的原因,左右兒子就不能通過完全二叉樹找左右兒子那種方式來找了,必須要記錄自己的左右兒子編號。

假設當前主席樹是前\(i-1\)次操作之后的成果,根為\(root[i-1]\),一共有\(tot\)個結點,現在要進行第\(i\)次操作。

1、令\(root[i]\)=\(++tot\),\(p=root[i-1],q=root[i]\)

2、如果要修改的點在左兒子子樹內,並且\(p\)不為\(0\),那么就令\(q\)的右兒子等於\(p\)的右兒子。然后新建一個點給\(q\)當左兒子,\(q=ls[q],p=ls[p]\)。右兒子以此類推

3、如果到這條修改路徑的底端則回溯更新結點信息,否則重復第二步。

這樣子建出來的主席樹,從\(root[i]\)開始訪問,就可以訪問到\(1\)\(i\)次操作之后的數據結構了。因為每次只會新建\(logn\)個結點,所以空間復雜度只會隨着修改次數緩慢增長,而線段樹作為主席樹的本質內部結構,時間復雜度也能過關,就這樣,主席樹就建好了。但是如果要區間修改的話,還需要一些騷操作,這里就不講了。


免責聲明!

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



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