OOP & Pointer: Segment Tree
前段时间有学了程设的同学问了我了几个题,好像要用指针实现一个链表类。
仔细回想起来,这么多年,写了这么多代码了,我从来没用指针实现过什么数据结构,也没真正写过一个什么数据结构类。
汗颜啊。
于是就写了这个 OOP & Pointer 的线段树。
我很喜欢线段树,它是我第一个学会的高级数据结构,写起来就会有一种安心的感觉。
从前集训有时候烦得受不了的时候,我就会找个线段树题写一写,好像也形成了某种心理暗示。
总之各种奇怪的原因,就有了这个代码。
#include<bits/stdc++.h>
using namespace std;
template<class T>
inline T read() {
T x = 0;
char c = getchar();
while (c < '0' || '9' < c) c = getchar();
while ('0' <= c && c <= '9') {
x = (x << 1) + (x << 3) + c - 48;
c = getchar();
}
return x;
}
template<class T>
class Segment_Tree {
private:
class Node {
public:
T dat, tag;
int lef, rig;
Node *lef_son, *rig_son;
Node(T d, T t, T l, T r, Node *a = NULL, Node *b = NULL) {
dat = d, tag = t, lef = l, rig = r;
this -> lef_son = a;
this -> rig_son = b;
}
int length() {
return rig - lef + 1 ;
}
} *root;
void push_up(Node *nod) {
nod->dat = nod->lef_son->dat + nod->rig_son->dat;
}
void push_down(Node *nod) {
if (nod->lef_son != NULL) {
nod->lef_son->dat += nod->lef_son->length() * nod->tag;
nod->lef_son->tag += nod->tag;
}
if (nod->rig_son != NULL) {
nod->rig_son->dat += nod->rig_son->length() * nod->tag;
nod->rig_son->tag += nod->tag;
}
nod->tag = 0;
}
void build(Node *nod) {
if (nod->lef == nod->rig) {
nod->dat = read<T>();
} else {
int mid = (nod->lef + nod->rig) >> 1;
nod->lef_son = new Node(0, 0, nod->lef, mid);
nod->rig_son = new Node(0, 0, mid + 1, nod->rig);
build(nod->lef_son);
build(nod->rig_son);
push_up(nod);
}
}
T dlt;
int goal, goar;
void update(Node *nod) {
if (goal <= nod->lef && nod->rig <= goar) {
nod->dat += (nod->rig - nod->lef + 1) * dlt;
nod->tag += dlt;
} else {
int mid = (nod->lef + nod->rig) >> 1;
push_down(nod);
if (goal <= mid) update(nod->lef_son);
if (mid < goar) update(nod->rig_son);
push_up(nod);
}
}
T query(Node *nod) {
T ret = 0;
if (goal <= nod->lef && nod->rig <= goar) {
ret = nod->dat;
} else {
int mid = (nod->lef + nod-> rig) >> 1;
push_down(nod);
if (goal <= mid) ret += query(nod->lef_son);
if (mid < goar) ret += query(nod->rig_son);
}
return ret;
}
public:
void tre_build(int n) {
root = new Node(0, 0, 1, n);
build(root);
}
void seg_update(int lef, int rig, T val) {
goal = lef, goar = rig, dlt = val;
update(root);
}
T seg_query(int lef, int rig) {
goal = lef, goar = rig;
return query(root);
}
};
Segment_Tree<long long> seg;
int main() {
int n, m;
n = read<int>(), m = read<int>();
seg.tre_build(n);
for (int i = 0; i != m; ++i) {
int key = read<int>();
int lef = read<int>(), rig = read<int>();
if (key == 1) seg.seg_update(lef, rig, read<long long>());
else cout << seg.seg_query(lef, rig) << endl;
}
return 0;
}