樹狀陣列區間修改區間查詢

2022-04-10 06:57:09 字數 2882 閱讀 6281

題面

首先,我們要推乙個柿子。

\(\displaystyle\sum_^ a[i]\)

把a[i]用差分陣列表示出來,就可以寫成

\(\displaystyle\sum_^\sum_^ d[i]\)

我們考慮一下,每個d[i]出現的次數是一定的。

那我們可以換一下列舉順序,先列舉d[i]在列舉他出現的次數,就可以變成

\(\displaystyle\sum_^ d[i]\times (n-i+1)\)

再把後面的(n-i+1)拆成(n+1) - i

就可以變成\(\displaystyle\sum_^ d[i] \times (n+1) - d[i] \times i\)

也就是 \(\displaystyle\sum_^ d[i] \times (n+1)\) - \(\displaystyle\sum_^ d[i] \times i\)

然後我們可以把前面的(n+1)提出來變成

\((n+1)\times \displaystyle\sum_^ d[i] - \displaystyle\sum_^ d[i] \times i\)

後面的兩個字首和就可以用樹狀陣列來維護,這樣樹狀陣列就可以支援區間修改和區間查詢。

求[l,r]的區間和可以用[1,r]的區間和減去[1,l-1]的區間和來求出來

\(\displaystyle\sum_^ a_i\)

= \(\displaystyle\sum_^\displaystyle\sum_^ d_i\)

= \(\displaystyle\sum_^ d_i\times (n-i+1)\)

= \(\displaystyle\sum_^ d_i \times (n+1) - d_i \times i\)

= \(\displaystyle\sum_^ d_i \times (n+1)\) - \(\displaystyle\sum_^ d_i \times i\)

= \((n+1)\times \displaystyle\sum_^ d[i] - \displaystyle\sum_^ d[i] \times i\)

#include#include#includeusing namespace std;

#define int long long

int n,m,opt,x,y,z,tmp;

int d[1000100],tr[1000010],a[1000010];

inline int read()

while(ch >= '0' && ch <= '9')

return s * w;

}int lowbit(int x)

void chenge(int x,int val)

}void modify(int x,int val)

}int ask(int x)

return ans;

}int query(int x)

return ans;

}signed main()

while(m--)

if(opt == 2)

} return 0;

}

二維樹狀陣列其實和一維的差不多。

你可以形象的理解為先對每一行求乙個樹狀陣列,在用樹狀陣列的方式把他們加起來。

例題操作1就是普通的單點修改,直接在原來的迴圈裡面再套一層迴圈每一行的樹狀陣列就可以了。

操作2的話比較麻煩,我們考慮一下容斥原理。

我們可以用整個矩形的面積減去綠色矩形的面積減去黃色矩形的面積,在加上陰影部分的面積。

已就是

ask(c,x2,y2) - ask(c,x1-1,y2) - ask(c,x2,y1-1) + ask(x,x1-1,y1-1)
下面這張圖可能會更形象些

}至於二維樹狀陣列的其他操作,蒟蒻我還沒學會,暫且先咕著吧qaq。

樹狀陣列求逆序對

#include#include#includeusing namespace std;

char ch;

int n,tr[1000010],b[1000010],a[50][100010],num[30],cnt[30];

long long ans;

int lowbit(int x)

void chenge(int x,int val)

int ask(int x)

int main()

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

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

printf("%lld\n",ans);

return 0;

}

樹狀陣列 區間修改,區間查詢

也許更好的閱讀體驗 好東西,以後可以不打線段樹了 本篇假定讀者都會最基礎的兩種樹狀陣列,即區改單查和單改區查 思考如何維護乙個區間的值,想到了差分 對乙個差分陣列做一次字首和可以得到每個位置的值 再對每個位置累加一下就是乙個區間的值 公式化的講,就是 設差分陣列為 c 則每個位置的值 val i s...

樹狀陣列高階 區間修改 區間查詢

區間修改與區間查詢 今天老糊塗了,樹狀陣列忘記了,基本的只要單點修改 區間查詢功能,如果要進行區間加操作,需要把樹狀陣列進行改造。我們首先來回顧樹狀陣列的功能 lowbit x x 返回二進位制最低位 1的值 比如 x 1010 那麼lowbit值為2 x lowbit x 把最後一位二進位制最低位...

樹狀陣列的應用(區間修改 區間查詢)

樹狀陣列之 區間修改 區間查詢 樹狀陣列的工作是 對一組資料進行快速修改查詢操作 最基本的功能是 單點修改 區間查詢。然後厲害的是 區間修改 單點查詢 用陣列del i 表示原陣列a i a i 1 的值 更厲害的來了。區間修改 區間查詢 用陣列del i 記錄原陣列a i 與前一項和,即del i...