樹狀陣列的知識總結

2022-03-03 02:24:16 字數 2731 閱讀 6591

單點修改:

不需要差分

區間修改,單點查詢: //參考

假設現在有乙個原陣列a(假設a[0] = 0),有乙個陣列d,d[i] = a[i] - a[i-1],那麼

a[i] = d[1] + d[2] + .... + d[i]

d陣列就是差分陣列

所以求a[i]就可以用樹狀陣列維護d[i]的字首和

區間修改,單點查詢:

根據d的定義,對[l,r]區間加上x,那麼a[l]和a[l-1]的差增加了x,a[r+1]與a[r]的差減少了x,所以就對差分陣列的字首和進行修改

設c是差分陣列的字首和

注意:差分 輸入的時候要以差的形式

for(int i=1;i<=n;i++)

void add(int x,int

k)

int sum(int

x)

區間修改,區間查詢:

根據上面的差分陣列的定義可以得到:

a[1] + a[2] + a[3] + ... + a[k] = d[1] + d[1] + d[2] + d[1] + d[2] + d[3] + ... + d[1] + d[2] + d[3] + ... + d[k]

= σ(k - i + 1) * d[i]  (i從1到k)

變化一下 σa[i] (i從1到k) = σ(k+1) * d[i] - i * d[i] (i從1到k)

d[i]可以用乙個字首和維護,i * d[i]也可以用乙個字首和進行維護,所以區間修改,區間查詢就變得很方便了

假設c1維護d[i]的字首和,c2維護d[i] * i的字首和

void add(int x,int

y)

int sum(int

x)

return ans1 -ans2;

}

樹狀陣列求 逆序對:

方法1的部落格

(但有0就死迴圈了,所以前提a[i]>0)

但又侷限性,a[ i ]的最大值不能很大,否則陣列會爆

因此,引進離散化+樹狀陣列

方法2的部落格

a[i].num  3 7 2 4 6

a[i].pos   1 2 3 4 5

對結構體a按num值從小到大排序,得到:

a[i].num  2 3 4 6 7

a[i].pos   3 1 4 5 2

for(int i=1;i<=n;i++)  aa[ a[i].pos ]=i;   會得到:

i:     1 2 3 4 5

aa[i]:    2 5 1 3 4

這樣的 aa[i]中各位數字 2 5 1 3 4的相對大小和原陣列a[i].num  3 7 2 4 5 是一樣的。這樣做減少了不必要的空間。 a[i] 可為0

去重離散化的兩種方法:

struct

node

aa[n];

bool

cmp(node x,node y)

intmain()

a[aa[i].p] =cnt;}}

去重離散化1

for(i=1;i<=n;++i) cin>>a[i], b[i]=a[i];

void

discretize()

去重離散化2

vectorv;

sort(v.begin(), v.end());

v.erase(unique(v.begin(), v.end()) , v.end());

...=lower_bound(v.begin(), v.end(), x) - v.begin() + 1;

去重離散化3

第二種去重不太徹底,5 8 8 10,離散化之後是 1 2 2 4

hdu二維樹狀陣列題:新年彩燈2

思路:二維轉為多個一維的就行了

1 #include2 #include3 #include 4 #include5 #include6 #include7 #include

8 #include9 #include

10 #include11 #include12 #include13 #include14

using

namespace

std;

15#define ll long long

16#define mem(a,x) memset(a,x,sizeof(a))

17#define se second

18#define fi first

19const ll mod=1e9+7;20

const

int inf= 0x3f3f3f3f;21

const

int n=1e6+5;22

23int c[1005][1005

];24

intn,m;

2526

int lowbit(int

i)27

3031

void add(int x,int y,int

k)32

3536

int sum(int x,int

y)37

4243

intmain()

4462}63

else

6471

}72 }

**

樹狀陣列總結

樹狀陣列的基本知識已經被各種大牛和菜鳥講到爛了,我就不多說了,下面給出基本操作的 假定原陣列為a 1.n 樹狀陣列b 1.n 考慮靈活性的需要,使用int a傳陣列。define lowbit x x x int sum int a,int x void update int a,int x,int...

樹狀陣列總結

樹狀陣列是對乙個陣列改變某個元素和求和比較實用的資料結構。兩中操作都是o logn 在解題過程中,我們有時需要維護乙個陣列的字首和s i a 1 a 2 a i 但是不難發現,如果我們修改了任意乙個a i s i s i 1 s n 都會發生變化。可以說,每次修改a i 後,調整字首和s在最壞情況下...

樹狀陣列總結

今天學習了一下樹狀陣列,做乙個簡單總結。樹狀陣列可分為兩種操作,1 修改單個點,統計區間和 一般為 向上修改 update1 向下統計 sum1 2 修改區間,統計單個點 一般為向下修改 update2 向上統計 sum2 主要模板如下 int c n int lowbit int x 用於確定區間...