樹狀數組求區間最大值一類問題

來源:互聯網
上載者:User

樹狀數組(Binary Index Tree)利用二進位的一些性質巧妙的劃分區間,是一種編程,時間和空間上都十分理想的求區間和的演算法,同樣我們可以利用樹狀數組優美的區間劃分方法來求一個序列的最值

約定以 num[]  表示原數組, 以 idx[] 表示索引數組, Lowbit(x)=x&(-x) 

樹狀數組求和時通過構造數組 idx[] 使 idx[k]=sum(num[tk]), tk [k-Lowbit(k)+1,k], 使用同樣的方法構造最值索引數組:

以最大值為例, 先討論詢問過程中不對數組做任何修改的情況, 用 idx[k] 記錄 [k-Lowbit(k)+1,k] 區間內的最大值, 可以仿照求和時的方法得到:

1234567 void
Init(
int n){     for(int
i=1;i<=n;i++){         for(int
j=i;j<=n;j+=Lowbit(j)){             idx[j]=MAX(idx[j],num[i]);
        }
    }
}

這種方法在每次調用該函數前都必須對數組進行初始化, 這樣對於資料範圍比較大的時候不是很優美, 這樣我們可以改為:

12345678 void
Init(
int n){      for(int
i=1;i<=n;i++){           idx[i]=num[i];
          for(int
j=1;j<Lowbit(i);j<<=1){                idx[i]=MAX(idx[i],idx[i-j]);
          }
     }
}

這樣, 在更新到第k個數時, 所有 t(t<k) 都已經是正確的值了, 不存在上面那個函數的情況了

然後再來看查詢的問題, 對於區間 [l,r] 把該區間轉化為多個的小區間再進行求最值, 方法是從後往前對每一個索引數的範圍進行判斷, 如在進行到第k項時,該數控制的範圍是 [k-Lowbit(k)+1,k], 如果k-Lowbit(k)+1在所求的範圍內的話則將該區間的最值加入最值的判斷,然後轉至地k-Lowbit(k),否則的話就只對第k個數進行最值判斷,然後轉至k-1,具體實現如下:

1234567891011 int
Query(
int l,int
r){      int
ans=num[r];      while(true){
          ans=MAX(ans,num[r]);
          if(r==l)
break;           for(r-=1;r-l>=Lowbit(r);r-=Lowbit(r)){
               ans=MAX(ans,idx[r]);
          }
     }
     return
ans; }

該查詢的複雜度為log(n)

st演算法的複雜度 O(nlog(n)) / O(1) , 線段樹為 O(nlog(n)) / (log(n)),樹狀數組 O(<nlog(n)) / O(log(n))

空間複雜度 st 為 O(nlog(n)), 線段樹 O(n),常數較大 , 樹狀數組是 O(n)

編程上 st 和 樹狀數組 都比較容易實現,線段樹代碼較長

另外線段樹靈活性較大

PKU 3264 題:

st    Memory: 6372K  Time: 1250MS  964B

BIT  Memory: 716K  Time: 1282MS  933B

SegTree  未測,要比st更大

然後我們可以進一步擴充到邊查詢邊修改的情況

每次直接去更新父親節點自然是不行的, 為了維護索引數組的正確性,我們在對每個父親節點進行更新時都要查詢他的所有兒子節點,在其中取最優值, 得到代碼如下:

123456789 void
Modify(
int p,int
v,int
n){
    num[p]=v;
    for(int
i=p;i<=n;i+=Lowbit(i)){         idx[i]=v;
        for(int
j=1;j<Lowbit(i);j<<=1){             idx[i]=MAX(idx[i],idx[i-j]);
        }
    }
}

複雜度為 O(log^2(n)),  HDU 1754  I hate it  437MS  1776K

另外,該方法還有一個減枝, 很容易想到,在求最大值時,當某個值更新的值大於原值的時候是沒有必要再去查詢兒子節點的,所以內部迴圈可加一個判斷來判定是否需要掃描兒子節點,可能是資料問題,該題時間並沒有大的變化

 

轉載請註明出處:http://www.cnblogs.com/ambition/archive/2011/04/06/bit_rmq.html 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.