其他分享
首页 > 其他分享> > OOP & Pointer: Segment Tree

OOP & Pointer: Segment Tree

作者:互联网

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;
}

标签:Node,lef,nod,Segment,son,int,OOP,rig,Pointer
来源: https://www.cnblogs.com/Shimarin/p/14225903.html