高階版樹狀陣列

2021-09-24 17:56:42 字數 1580 閱讀 5424

我們都知道樹狀陣列一般有兩種形式

1.最為傳統的版本,支援區間求和,單點修改

2.差分樹狀陣列 支援區間修改,單點查詢

而高階版樹狀陣列 可支援 區間求和,區間修改

其原理是:

設tree[i]=a[i]-a[i-1](差分),那麼容易得到:

tree[1]+tree[2]+……+tree[i]=a[i]這個公式

維護tree陣列即可以實現區間修改了。

接下來是區間查詢的實現問題

我們已經推出了乙個公式:

tree[1]+tree[2]+……tree[i]=a[i]
那麼,對於1到r的區間和,即為:

a[1]+a[2]+……+a[r-1]+a[r]

//用上方公式推導得出

=tree[1]+(tree[1]+tree[2])+……+(tree[1]+……+tree[r])

//根據加法交換律與結合律:

=(tree[1]*(r))+(tree[2]*(r-1))+……(tree[r]*1)

//那麼:

=r*(tree[1]+tree[2]+……+tree[r])-(tree[1]*0+tree[2]*1+……+tree[r]*(r-1))

看到這裡,是不是已經很清晰了呢?

對於a的樹狀陣列(差分)tree,建立乙個新的樹狀陣列tree1使得:

tree1[i]=tree[i]*(i-1)

之後,x到y的區間和即為:

(y*query(tree,y)-(x-1)*query(tree,x-1))-(query(tree1,y)-query(tree1,x-1))

p3372 【模板】線段樹 1

這種樹狀陣列可以實現線段樹的某些功能

#include#define rg register

#define inf 2147483647

#define min(a,b) (ab?a:b)

#define ll long long

#define maxn 100005

const double eps=1e-8;

using namespace std;

inline ll read()

while(ch>=48&&ch<=57)

return s*w;

}inline void write(ll x)

ll n,m;

ll tree[maxn],tree1[maxn];

inline ll lb(ll x)

inline void add(ll *tree,ll x,ll k)

}inline ll query(ll *tree,ll x)

return ans;

}int main()

for(rg ll i=1;i<=m;i++)

else if(x==2)

}return 0;

}

樹狀陣列高階

csdn同步 前置知識 下面我們考慮區間修改。一開始我們維護的是部分字首和,但是現在,區間修改顯然不能用字首和有關的做法。單區間修改用差分就夠了。但是這裡有修改,考慮將差分和樹狀陣列結合。令 c 為 a 的差分,維護 a 的區間修改與區間和即可,這樣 a 就是 c 的字首和了。那麼區間修改只需要改 ...

樹狀陣列 演算法高階專題

lowbit i i i 或者i i i i 1 9 and 1 1 要點 乙個數i對應二進位制表示未尾0的個數為k,那麼他管轄的範圍為 從i到左邊i 2 k 1的2 k 個元素。如 i 6 110 k 1 6管轄的範圍為 c 5 a 5 a 6 2 1 管2個。2 求前n個元素的和,n的二進位制的...

「高階」資料結構 樹狀陣列!

最簡單的樹狀陣列就是這樣的 void add int p,int x int ask int p int range ask int l,int r 通過 差分 就是記錄陣列中每個元素與前乙個元素的差 可以把這個問題轉化為問題1。設原陣列為a i 設陣列d i a i a i 1 a 0 0 則 a...