ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OOP & Pointer: Segment Tree

2021-01-03 16:34:48  阅读:256  来源: 互联网

标签:Node lef nod Segment son int OOP rig Pointer


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有