zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    test6
    test4
    test3
    20165321 2017-2018-2《Java程序设计》课程总结
    20165321 实验五 网络编程与安全-2
    20165321 实验五 网络编程与安全
    实验四 Android开发基础
    20165321 实验三 敏捷开发与XP实践
    《深入理解计算机系统》第三章 程序的机器级表示学习
    《文献管理与信息分析》第二章
  • 原文地址:https://www.cnblogs.com/Shimarin/p/14225903.html
Copyright © 2011-2022 走看看