樹狀數組[數據結構]
阿新 • • 發佈:2017-07-25
需要 結構 例子 img return 二進制 應該 date ash ,lowbit(6)=(10)2=2;
樹狀數組
——!x^n+y^n=z^n
額,圖是網上搜來的...
如圖:
我們令
c[1]=a[1]
c[2]=a[2]+c[1]
c[3]=a[3]
c[4]=a[4]+c[3]+c[2]
c[5]=a[5]
c[6]=c[5]+a[6]
c[7]=a[7]
c[8]=a[8]+c[4]+c[6]+c[7]
c[9]=a[9]
其實我們是令c[n]的管轄範圍為i個元素,而這個i為n化為二進制時從後往前第一個出現1的地方及後面的0組成數的大小(記為lowbit(n))。
舉個例子c[6]=a[5]+a[6]
6=(110)2
但這會產生一個問題,怎麽求lowbit?
利用計算機補碼特性我們可以得到:
lowbit(x)=x&(-x)。[知道補碼的同學手推即可,不知道趕緊百度]
當然作為數據結構要有他的用處。
利用樹狀數組我們可以進行兩個比較簡單的操作:
<i>求a[1]+a[2]+L+a[x]的值
<ii>單點更新
<i>區間查詢
假設我們要求1~x的區間和,我們可以先查詢c[x],顯然c[x]是包含於我們要求的範圍裏的;
但當我們查詢完c[x]後,我們應該繼續查詢未查詢到的部分;
註意到:c[x]的管轄範圍:[x-lowbit(x)+1,x],故我們應繼續查詢c[x-lowbit(x)];
反復上面操作直至查詢完畢。
代碼:
1 int getsum(x){ 2 int res=0; 3 for(;x;x-=lowbit(x)) 4 res+=bit[x]; 5 return res; 6 }
本人樹狀數組一直喜歡打成bit啊...
<ii>單點更新
我們希望a[x]+inc
當然我們會先讓c[x]+inc;
然後我們需要找到管轄c[x]的c[y],因為x必須∈[y-lowbit(y)+1,y],我們怎麽做這件事?
其實我們只需要在x後面補上一個0就行了,想想是不是這樣。
代碼:
1 void update(x,inc){ 2 for(;x<=n;x+=lowbit(x)) 3 bit[x]+=inc; 4 }
怎麽樣,是不是覺得代碼簡短很多?(對比線段樹)
樹狀數組[數據結構]