这是我第一题AC的线段树
生活随笔
收集整理的這篇文章主要介紹了
这是我第一题AC的线段树
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目簡述: 有N個整數(shù),Q次操作,每次操作為詢問一個區(qū)間[a, b]內(nèi)數(shù)的和(0號操作)或者把一個區(qū)間內(nèi)的數(shù)全部加上v(1號操作)
線段樹求解即可。
#include <cstdio> #include <algorithm> using std::min; using std::max; #define L(no) ((no) << 1) #define R(no) (L(no) | 1) #define PLUSTAG(no, val) plustag[no] += val, query[no] += val*(rb[no]-lb[no]+1) const int MAXN = 400001; int lb[MAXN], rb[MAXN], query[MAXN], ans, plustag[MAXN]; int sum(int a, int b) {return a + b;} void build(int no, int l, int r) {int mid = l + r >> 1;lb[no] = l;rb[no] = r;if(l == r) scanf("%d", &query[no]);else {build(L(no), l, mid);build(R(no), mid + 1, r);query[no] = query[L(no)] + query[R(no)];} } void getval(int no, int l, int r, int(*func)(int, int), int* key) {int mid = lb[no] + rb[no] >> 1;if(l <= r && (lb[no] <= r&& rb[no] >= r || rb[no] >= l && lb[no] <= l)) {if(lb[no] == l && rb[no] == r) ans = func(ans, key[no]);else {if(plustag[no]) {PLUSTAG(L(no), plustag[no]);PLUSTAG(R(no), plustag[no]);plustag[no] = 0;}getval(L(no), l, min(mid, r), func, key);getval(R(no), max(l, mid + 1), r, func, key);}} } void plus(int no, int l, int r, int val) {int mid = lb[no] + rb[no] >> 1;if(l <= r && (lb[no] <= r&& rb[no] >= r || rb[no] >= l && lb[no] <= l)) {if(lb[no] == l && rb[no] == r) {PLUSTAG(no, val);}else {if(plustag[no]) {PLUSTAG(L(no), plustag[no]);PLUSTAG(R(no), plustag[no]);plustag[no] = 0;}query[no] += (r - l + 1) * val;plus(L(no), max(l, lb[no]), min(mid, r), val);plus(R(no), max(l, mid + 1), min(r, rb[no]), val);}} } int main() {int n, q, i, op, a, b, v;scanf("%d%d", &n, &q);build(1, 1, n);for(i = 1; i <= q; i++) {scanf("%d%d%d", &op, &a, &b);if(op == 0) {ans = 0;getval(1, a, b, sum, query);printf("%d\n", ans);}else {scanf("%d", &v);if(v != 0) plus(1, a, b, v);}}return 0; }解釋一下:query[]表示一個區(qū)間里面的和……然后左右半?yún)^(qū)間分別搞……1操作時Lazy優(yōu)化是必須要加的(就是好像老師布置的作業(yè)等要交了再補(bǔ)……),然后,便過之。
問我為什么getval寫函數(shù)指針?因?yàn)檫@是百搭函數(shù)……要求最大值傳入max最小值傳min求和傳sum……
然后:就沒有然后了。過之。
轉(zhuǎn)載于:https://www.cnblogs.com/nealchen/p/4290085.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的这是我第一题AC的线段树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何评价华晨宇当选华语乐坛内地一哥?
- 下一篇: 有没知道东极租牌的目标是