樹狀陣列 P3372 模板 線段樹 1

2022-04-16 22:02:27 字數 1194 閱讀 5833

給定乙個長度為 \(n\) 的序列,有 \(m\) 次操作,要求支援區間加和區間求和。

\(1 \leq n,~m \leq 10^5\) 序列元素值域始終在long long範圍內。要求使用樹狀陣列解決

sb線段樹板子題

一直聽說這題有樹狀陣列做法,今天剛剛明白。

首先區間加和區間求和可以轉化成字首修改和字首求和。

考慮乙個字首加操作update(x, v)對一次字首查詢query(y)的貢獻。

當 \(x \leq y\) 時,貢獻為 \(x \times v\)

當 $ x > y$ 時,貢獻為 \(y \times v\)

考慮分別維護這兩種貢獻。用第乙個序列維護第一種貢獻,每次進行update(x, v)時在序列 \(x\) 處加上 \(x \times v\),代表每個 查詢query(y)\((y \geq x)\) 都被加上了 \(x \times v\) 的貢獻;用第二個序列維護第二種貢獻,在進行update(x, v)時在 \(x\) 處加上 \(v\),代表每個查詢query(y)\((y < x)\) 都會被加上 \(y \times v\) 的貢獻。

對於每個查詢query(y),其答案顯然是 \(qa(y) + (qb(n) - qb(y)) \times y\),其中 \(qa\) 代表對第乙個序列做字首查詢,\(qb\) 代表對第二個序列做字首查詢。那麼直接用樹狀陣列維護這兩個貢獻即可。

#include const int maxn = 100005;

int n, m;

struct bit

void update(int p, const ll &v)

ll query(int p)

};bit leq, geq;

void update(int p, const ll &v);

ll query(int p);

int main()

for (ll x, y, z; m; --m) else

} return 0;

}void update(int i, const ll &v)

ll query(const int p)

P3372 模板 線段樹 1

線段樹學習 這個題來看,線段樹分為建樹,更新,查詢。1.建樹 void build ll p,ll l,ll r ll mid l r 1 build lson p l,mid build rson p mid 1,r push up sum p void push up sum ll p 這段 的...

P3372 模板 線段樹 1

題 include includeusing namespace std typedef long long ll ll n,m,ans,x,y,op,val 因為下面有的函式需要用到x,y,val值,懶得傳參,故直接寫為全域性變數 const int n 100000 struct nodetre...

P3372 模板 線段樹 1

題目描述 如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 輸入輸出格式 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含3或4個整數...