談區間合并線段樹

來源:互聯網
上載者:User

對於以前做的區間合并線段樹頗有微詞,對於大神們使用三個數組來記錄節點的情況很是不解。對於當前點,只需要能提供所需的w長度區間即可向下進行判斷,左子樹優先提供,左右子樹合并提供,右子樹最後提供,否則輸出不可行。

故我認為只需要一個記錄當前節點的情況的數組即可,不需要三個數組,故用一個數組實際編寫了代碼。後發現此法是不行的.... 首先判斷左右子樹能否提供的問題,lsum+rsum>=w則返回m-lsum+1,這樣用三個數組很方便,若用一個數組會有很多bug,因為一個數組只是記錄自己的情況:左右子樹提供給自己的東西。而沒有考慮區間的連續性。舉例來說:1-10的線段樹,左子樹右子樹分別提供4,但是5,6兩點已經被占,這時要提供8長度的區間顯然不可能,但是只用一個數組會出現可行的情況而且答案是2.為何要使用三個數組?因為我對這些數組各自的功能不是很清楚,現在來看,lsum與rsum有各自的用處。lsum,rsum各自記錄當前點向左向右的連續區間各多長,也就是說這兩個數組實際上起的作用就是用來判斷區間連續與否。

void PushUp( int rt,int m ) { lsum[rt]=lsum[rt<<1]; //當前lsum直接取左子樹的lsum[]值 rsum[rt]=rsum[rt<<1|1]; //當前sum直接取右子樹的rsum[]值 if( lsum[rt]==(m-(m>>1)) )lsum[rt]+=lsum[rt<<1|1];//若左子樹是滿的,則向右拓展 求和 if( rsum[rt]==m>>1 )rsum[rt]+=rsum[rt<<1];//若右子樹是滿的,則向左拓展 求和 msum[rt]=max( lsum[rt<<1|1]+rsum[rt<<1],max( msum[rt<<1],msum[rt<<1|1]) ); //當前msum的值為左右子樹中空閑點,和 左子樹的右邊和右子樹的左邊的和中最大值 } 

合并區間的重要操作就在於PushUp操作中,其他的地方lsum與rsum用法相同,共同更新,這也是我產生錯覺的原因。看來對於理解這些演算法真的很是重要啊~ 我果然還是太弱了!加油!!










聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.