poj 3468 线段树
生活随笔
收集整理的這篇文章主要介紹了
poj 3468 线段树
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
線段樹的 建立build(初始化+左右相等+兩個(gè)遞歸+別忘了sum)+更新update(遞歸出口+更新delta+三向遞歸+修正當(dāng)前節(jié)點(diǎn)的value)+查找query(如果左右相等+更新delta+三種遞歸)
#include<iostream> using namespace std;#define L(root) ((root) << 1) #define R(root) (((root) << 1) + 1)const int MAXN = 100001; int numbers[MAXN];struct st {// 區(qū)間范圍int left, right;// 更新值、區(qū)間總和long long delta, sum; } st[MAXN * 4];// 建樹代碼基本不變 void build(int root, int l, int r) {st[root].left = l, st[root].right = r, st[root].delta = 0;if (l == r) {st[root].sum = numbers[l];return;}int m = l + ((r - l) >> 1);build(L(root), l, m);build(R(root), m + 1, r);st[root].sum = st[L(root)].sum + st[R(root)].sum; }long long query(int root, int l, int r) {// 如查詢區(qū)間恰等于節(jié)點(diǎn)區(qū)間,直接返回該區(qū)間總和即可if (st[root].left == l && st[root].right == r) {return st[root].sum;}// 否則需將當(dāng)前區(qū)間的“緩沖”值更新下去并修正各節(jié)點(diǎn)區(qū)間的總和if (st[root].delta) {st[L(root)].delta += st[root].delta;st[R(root)].delta += st[root].delta;st[L(root)].sum += st[root].delta * (st[L(root)].right - st[L(root)].left + 1);st[R(root)].sum += st[root].delta * (st[R(root)].right - st[R(root)].left + 1);st[root].delta = 0;}int m = st[root].left + ((st[root].right - st[root].left) >> 1);if (r <= m) {return query(L(root), l, r);} else if (l > m) {return query(R(root), l, r);} else {return query(L(root), l, m) + query(R(root), m + 1, r);} }void update(int root, int l, int r, long long v) {// 如變更區(qū)間恰等于節(jié)點(diǎn)區(qū)間,只修正當(dāng)前節(jié)點(diǎn)區(qū)間即可if (st[root].left == l && st[root].right == r) {st[root].delta += v;st[root].sum += v * (r - l + 1);return;}// 否則需向下修正相關(guān)節(jié)點(diǎn)區(qū)間if (st[root].delta) {st[L(root)].delta += st[root].delta;st[R(root)].delta += st[root].delta;st[L(root)].sum += st[root].delta * (st[L(root)].right - st[L(root)].left + 1);st[R(root)].sum += st[root].delta * (st[R(root)].right - st[R(root)].left + 1);st[root].delta = 0;}int m = st[root].left + ((st[root].right - st[root].left) >> 1);if (r <= m) {update(L(root), l, r, v);} else if (l > m) {update(R(root), l, r, v);} else {update(L(root), l, m, v);update(R(root), m + 1, r, v);}// 同時(shí)一定要記得修正當(dāng)前節(jié)點(diǎn)區(qū)間的總和st[root].sum = st[L(root)].sum + st[R(root)].sum; }int main() {int N, Q;while (cin >>N >> Q) {for (int i = 1; i <= N; ++i) {cin >> numbers[i];}build(1, 1, N);char cmd;int l, r;long long v;while (Q--) {cin >>cmd;cin >>l>>r;switch (cmd) {case 'Q':cout<<query(1, l, r)<<endl;break;case 'C':cin >> v;if (v) {update(1, l, r, v);}break;}}}return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/lipenglin/p/4395743.html
總結(jié)
以上是生活随笔為你收集整理的poj 3468 线段树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Delphi中uses在interfea
- 下一篇: 【原创】Kakfa metrics包源代