給定乙個長度為 \(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個整數...