樹狀陣列(binary indexed tree(bit), fenwick tree)是乙個查詢和修改複雜度都為log(n)的資料結構。主要用於查詢任意兩位之間的所有元素之和,但是每次只能修改乙個元素的值;經過簡單修改可以在log(n)的複雜度下進行範圍修改,但是這時只能查詢其中乙個元素的值。
樹狀陣列,載體還是陣列,但是它又有幾分線段樹的味道,陣列本身就記錄了某一段的值:
我們看這張圖:
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];
所謂的求區間和比較快的演算法,本質其實就是在第一次操作是已經算好了,最後只要調出來就好了;
我們再來看看樹狀陣列每一位包含數字的個數,不難發現c[n]所含數字個數等於2^k(k是n換做二進位制後末尾0的個數);
有個演算法可以簡單搞定2^k;
int lowbit(int x)
至於原因嗎。。。。。。。。我也不會;
單點
更新操作
void update(int x,int num)
}
和線段樹一樣單點更新之後必須要向上更新直到根節點(這裡是最後一位n);
比如你修改了a[2]的值,那麼向上2,4,8都需要更新;
區間更新操作
這裡和線段樹也相似但是是需要兩次修改後的單點操作
void update(int x,int num)
}
將左右區間分別帶入就可以了;
例如將x1到x2的數值+1,就update(x1,1),update(x2,-1);
求和操作
int getsum(int x)
return sum;
}
求前a[x]的總和,那一定有x個數,每次減去lowbit就是將x二進位制中的1去掉乙個;
綜上樹狀陣列講完!
字尾陣列題目選講
複習題 luogu題單 1.noi2015 品酒大會 題意 forall i 0,n 求有多少對字尾滿足 lcp ge i 以及滿足條件的兩個字尾的權值乘積的最大值。我們統計出對於 1.n 中的每個 i 統計一下有多少個 lcp i 再做個字尾和。因為 lcp i,j min st times ed...
線段樹選講
線段樹選講 線段樹是一種二叉搜尋樹 與區間樹 相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中的每乙個非葉子節點 a,b 它的左兒子表示的區間為 a,a b 2 右兒子表示的區間為 a b 2 1,b 因此線段樹是平衡二叉樹 最後的子節點數目為n,即整個線段區...
CodeChef題目選講
關鍵點 不超過7條 根據咕咕原理,所以答案最少是n 7 n小於49就暴力 隨機化找兩個點判斷直線上的點個數,隨機500次,概率就很高了 法二 點數大於50,答案至少是8 答案一定是7條路之一 隨機找7個點,按照級角序排序,點數大於7的直線就刪去上面的點 之後random不考慮,但是實際上不能真刪除,...