HDU - 5919 Sequence II——主席树+区间种类++逆序建树
生活随笔
收集整理的這篇文章主要介紹了
HDU - 5919 Sequence II——主席树+区间种类++逆序建树
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
【題目描述】
HDU - 5919 Sequence II
【題目分析】
題目給定一個數(shù)組,每次查詢一個區(qū)間,找出區(qū)間內(nèi)不同數(shù)字的個數(shù)x,然后輸出按出現(xiàn)順序第x/2向上取整個數(shù)字的位置。
- 按照要求,我們首先需要能夠找出給定區(qū)間不同的數(shù)字個數(shù)。
首先,我們分析一個簡單一些的問題:對于右端點固定的區(qū)間,如何計算不同左區(qū)間內(nèi)不同數(shù)字的個數(shù)。
我們不妨用一個數(shù)組記錄cntcntcnt哪些位置出現(xiàn)了一個不同的數(shù)字,用sumsumsum數(shù)組進行維護cnt[1..l]cnt[1..l]cnt[1..l]的和(可以用線段樹或者樹狀數(shù)組),那么對于區(qū)間[l,r][l,r][l,r]內(nèi)不同數(shù)字的個數(shù)就是sum[r]?sum[l?1]sum[r]-sum[l-1]sum[r]?sum[l?1]。
在從前往后進行添加的過程中,如果該數(shù)字在前面已經(jīng)出現(xiàn),就將前面的標記消除,在后面的位置進行標記,也就是說盡可能將標記后放。例如對于數(shù)組1,2,2,3,5,11,2,2,3,5,11,2,2,3,5,1維護以后的cntcntcnt數(shù)組就是0,0,1,1,1,10,0,1,1,1,10,0,1,1,1,1,這樣做的原因是我們假設的是右端點固定,對于重復的元素,在后面如果出現(xiàn)過前面就沒有必要標記。
如果詢問是離線的,我們大可以先將詢問保存下來,然后從前往后加入數(shù)據(jù)的過程中不斷將對應的詢問答案保存(對應是指右端點相同),最后輸出就可以了。
可是這個問題是強制在線的,所以我們必須使用主席樹進行可持久化。可是這種可持久化和以前的主席樹運用不同,因為在添加的過程中會將前面的標記消除,所以不同根節(jié)點的主席樹不在擁有可以互相加減的能力(加減的結果不再有意義)。然而在我們這個問題里面我們是不需要進行加減的。 - 不同于求區(qū)間第K大的時候我們的主席樹維護的是值區(qū)間,即值在區(qū)間內(nèi)的個數(shù),這里根節(jié)點的1..n1..n1..n指的是數(shù)據(jù)范圍aiaiai的最大值。在這里我們的根節(jié)點的1..n1..n1..n的nnn指的是數(shù)據(jù)的個數(shù),就是題目中的nnn,標記的是該位置上出現(xiàn)了一個之前沒有出現(xiàn)過的數(shù)字。 因此對于每次詢問,我們訪問的版本里保存的就是實際的數(shù)組,直接計數(shù)就可以。而區(qū)間第K大就需要減去之前的版本才是該區(qū)間內(nèi)的數(shù)的個數(shù)。
- 題目要求的是數(shù)據(jù)第一次出現(xiàn)的位置,可是按照上面的想法進行建樹的話我們保存的是當前區(qū)間[1,i][1,i][1,i]數(shù)據(jù)最后一次出現(xiàn)的位置。很自然,我們應該進行逆序建樹,這樣的話我們保存的就是[i,n][i,n][i,n]區(qū)間內(nèi)數(shù)據(jù)第一次出現(xiàn)的位置,對于需要查詢的區(qū)間[l,r][l,r][l,r],我們訪問第lll個版本的主席樹,就滿足題目要求啦。
求出數(shù)字的個數(shù)后我們再除以2向上取整就是題目要求的k,然后在找出對應的位置,這里類似區(qū)間第K大
【參考文獻】
大佬博客1
大佬博客2
【AC代碼】
總結
以上是生活随笔為你收集整理的HDU - 5919 Sequence II——主席树+区间种类++逆序建树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 芒果tv会员如何取消自动续费
- 下一篇: 成都大熊猫基地人工讲解收费标准