樹狀陣列是乙個查詢和修改複雜度都為o(logn)的資料結構,主要解決動態陣列字首和、區間和。
字首和、修改陣列元素
a1,a2,a3…an區間和詢問a1+a2+a3+…+am
修改ai(1<=i<=n)
暴力:複雜度o(n^2)
樹狀陣列:d[6]=a5+a6;
110 2^1
d[8]=a1+…+a8;
1000 2^3
如下圖,若要求14位置的字首和,僅需要計算d[14]+d[12]+d[8],每次查詢不超過logn個位置。單次查詢複雜度為o(logn)
查詢13這個位置的字首和:
13=1101
根據二進位制拆分:
1101 d[13] 其範圍內有2^0個元素
1100 d[12] 2^2
1000 d[8] 2^3
修改陣列值
修改d[5]:
倒回去求出覆蓋d[5]的區間–在最後乙個1的位置加一
101 d[5]
110 d[6]
1000 d[8]
區間和可轉化為字首和進行計算: [5,9]–>sum(9)-sum(5)
lowbit運算
lowbit (int x)intsum
(int x)
return res;
}void
add(
int x,
int v)
}//****************
intmain()
return0;
}//二維樹狀陣列/*
int d[
301]
[301];
void
update
(int x,
const
int&y,
const
int&v)
intgetsum
(int x,
const
int&y)
*/面試題51. 陣列中的逆序對
難度困難168收藏分享切換為英文關注反饋
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。
示例 1:
限制:輸入: [7,5,6,4]
輸出: 5
0 <= 陣列長度 <= 50000
離散化:相對於陣列中的值,我們其實更關心的是陣列中的元素的「相對排名」,為了避免開闢多餘的「樹狀陣列」空間,我們首先對陣列元素做預處理,這一步叫「離散化」;class solution
void
add(
int i,
int x)
}int
getsum
(int i)
return res;
}int
reversepairs
(vector<
int>
& nums)
return cnt;}}
;
具體的做法是:
先離散化,將所有的陣列元素對映到 0、1、2、3… ,這是為了節約樹狀陣列的空間;
從後向前掃瞄,邊統計邊往樹狀陣列裡面動態新增元素
樹狀陣列Day1題解 3 7 小結
單點修改,區間查詢 較水,咕咕 區間修改,單點查詢 將乙個區間的數同時加上乙個x,自然想到差分序列 p p i a i a i 1 我們還知道 a i p j 1 j i 證明 p i a i a i 1 p i p i 1 a i a i 1 a i 1 a i 2 a i a i 2 p i p...
day1 分割陣列
小白一名,0演算法基礎,艱難嘗試演算法題中,若您發現本文中錯誤,或有其他見解,往不吝賜教,感激不盡,拜謝。領扣 第915題 今日演算法 題幹 給定乙個陣列 a,將其劃分為兩個不相交 沒有公共元素 的連續子陣列 left 和 right,使得 left 中的每個元素都小於或等於 right 中的每個元...
day1 資料結構之陣列
1.要求輸入乙個整數n,用動態陣列a來存放2 n之間所有5或7的倍數,輸出該陣列。思路 先令乙個空陣列,再用if判斷語句把能把5或7整除的數找出來,再把這個數插進空陣列裡面。迴圈操作。def zhengchu n array for i in range 2 n 1 if i 5 0or i 7 0...