樹狀數組淺講

來源:互聯網
上載者:User

標籤:規律   遍曆   src   get   span   首碼   png   維護   images   

樹狀數組淺講

rt,個人膚淺理解,各位神犇請自動出門右轉

不同於傳統數組每個元素單獨存放,求和時遍曆相加,樹狀數組每個元素不單獨維護,而是被維護在一個包含其他元素的首碼和裡。宜先仔細揣摩後再行。

便體現了樹狀數組儲存資料的原理

相當於以下等式

說明:C[]是樹狀數組,A[]是實際元素

C[1]=A[1];

C[2]=A[1]+A[2];

C[3]=A[3];

C[4]=A[1]+A[2]+A[3]+A[4];

C[5]=A[5];

C[6]=A[5]+A[6];

C[7]=A[7];

C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];

如此儲存,便可以體現出上面所說每個元素不單獨維護,而是被維護在一個包含其他元素的首碼和裡的維護原則,比如元素1(即\(A[1]\))便包含在C[1],C[2],C[4],C[8]中,而如今有一個神器lowbit(x)=x&(-x)可以依次推出所有包含元素i的\(C[k]\)們,我們先看看1至8的lowbit值

lowbit(1)=1

lowbit(2)=2

lowbit(3)=1

lowbit(4)=4

lowbit(5)=1

lowbit(6)=2

lowbit(7)=1

lowbit(8)=8

這時你會發現一個規律:每次當前下標再加上當前下標的lowbit值便會得到下一個包含元素i的\(C[k]\)的下標,比如第一個包含元素1的\(C[k]\)為\(C[1]\),那麼下一個(第二個)包含元素1的\(C[k]\)為\(C[1+lowbit(1)]\),如此按照此規律迴圈便可訪問到所有包含元素i的\(C[k]\)們

於是下面遍曆所有包含元素i的\(C[k]\)的程式成立

void spot(int x){    for(int i=x;i<=n;i+=lowbit(i))        //do something}

於是你又可以在遍曆的同時順便修改一下值(又於是下面修改元素i的值的程式成立)

void add(int x, int v){    for(int i=x;i<=n;i+=lowbit(i))        tree[i]+=v;}

同理,你又會發現其實查詢首碼和的規律也是如此,讀者可以動手類比一下

於是查詢首碼和的程式又成立

int getsum(int x){    int ans=0;    for(int i=x;i>0;i-=lowbit(i))        ans+=tree[i];    return ans;}

完整的樹狀數組板子

int lowbit(int x){return x&(-x);}void add(int x, int v){    for(int i=x;i<=n;i+=lowbit(i))        tree[i]+=v;}int getsum(int x){    int ans=0;    for(int i=x;i>0;i-=lowbit(i))        ans+=tree[i];    return ans;}

以上。

樹狀數組淺講

聯繫我們

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