區間求和(線段樹和樹狀陣列)

2021-08-15 17:50:10 字數 1588 閱讀 7925

一. 線段樹

線段樹從零開始

線段樹詳解

lazy標記思想

一種二叉樹

開四倍空間

#define n 1000000

int sum[n<<2];//求和

int a[n];//存原陣列

1.建樹(存和)

(1).遞迴實現

void pushup(int rt)//更新  

void build(int l,int r,int rt)

int m=(l+r)>>1;

build(l,m,rt<<1); //左邊

build(m+1,r,rt<<1|1); //右邊

pushup(rt);

}

(2).非遞迴實現

void build(int n)  

}

2.點更新

a[l]+=c

(1).

void update(int l,int c,int l,int r,int rt)

int m=(l+r)>>1;

if(l <= m) update(l,c,l,m,rt<<1); //根據條件判斷往左子樹呼叫還是往右

else update(l,c,m+1,r,rt<<1|1);

pushup(rt);//子節點的資訊更新然後更新本節點

}

(2).

void update(int l,int c)  

}

3.區間更新

a[l,r]+c

void pushdown(int rt,int ln,int rn)  

}

void update(int l,int r,int c,int l,int r,int rt)  

int m=(l+r)>>1;

pushdown(rt,m-l+1,r-m);//下推標記

//左右子樹跟[l,r]有交集則遞迴

if(l <= m) update(l,r,c,l,m,rt<<1);

if(r > m) update(l,r,c,m+1,r,rt<<1|1);

pushup(rt);//更新本節點資訊

}

二. 樹狀陣列

sum[ ]存...如圖所示這種

然後神奇的x&(-x)

就求出最小1的位

int lowbit(int x)

//

更新

void update(int x, int num)

}

int getsum(int x)

return s;

}

樹狀陣列 區間求和

樹狀陣列 是乙個查詢和修改複雜度都為log n 的資料結構,假設陣列a 1.n 那麼查詢a 1 a n 的時間是 log n 級別的。所以如果要解決 陣列中的元素不斷被修改,怎麼才能快速地獲取陣列中連續m個數的和 這個問題的話,用樹狀陣列就再好不過了 首先,什麼是樹狀陣列呢?樹狀陣列就是用另外乙個陣...

區間操作 樹狀陣列 線段樹

涉及區間操作的一些套路必須要會呀 區間加減為了偷懶能不寫線段樹so我選擇樹狀陣列!但是區間乘除,最大值我想了想還是用線段樹分塊吧。這裡用網上的一張圖 這裡灰色陣列是原本的陣列 a i 紅色陣列則是樹狀陣列 c i 這裡直接給出結論 c i a i 2 k range 1,2 k k是i的二進位制位從...

區間操作 樹狀陣列 線段樹

涉及區間操作的一些套路必須要會呀 區間加減為了偷懶能不寫線段樹so我選擇樹狀陣列!但是區間乘除,最大值我想了想還是用線段樹分塊吧。這裡用網上的一張圖 這裡灰色陣列是原本的陣列 a i 紅色陣列則是樹狀陣列 c i 這裡直接給出結論 c i a i 2 k range 1,2 k k是i的二進位制位從...