自认为自己写的最美的线段树模板

Posted 玥~endlessly~vast

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自认为自己写的最美的线段树模板相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
using namespace std;
const int MAX = 100005;
typedef struct Node{
    long long val, tag;
    int l, r;
    Node *rson, *lson;
    int len() {return r - l;}
    int mid() {return (l + r) >> 1;}
    Node(): rson(NULL), lson(NULL), l(0), r(0), val(0), tag(0){}
}node, *pionter;

class Segment_Tree
{
    public:
        pionter rt = new Node();
        long long a[MAX];
    
    void PushUp(pionter rt)
        {
            rt->val = rt->rson->val + rt->lson->val;
        }
    
    void PushDown(pionter rt)
        {
            if(rt->tag)
                {
                    rt->lson->tag += rt->tag;
                    rt->rson->tag += rt->tag;
                    rt->lson->val += rt->tag * rt->lson->len();
                    rt->rson->val += rt->tag * rt->rson->len();
                    rt->tag = 0;
                }
        }
    
    void Build(pionter rt,int l, int r)
        {
            rt->l = l;
            rt->r = r;
            if(l + 1 == r)
                {
                    rt->val = a[l];
                    //rt->pos = l;
                    rt->rson = NULL;
                    rt->lson = NULL;
                    return ;
                }
            rt->rson = new Node();
            rt->lson = new Node();
            Build(rt->lson, l, rt->mid());
            Build(rt->rson, rt->mid(), r);
            PushUp(rt); 
        }
        
    void UpData(pionter rt, int L, int R, int k)
        {
            if(L <= rt->l && rt->r <= R)
                {
                    rt->val += k * rt->len();
                    rt->tag += k;
                }
            else
                {
                    if(rt->tag != 0)    PushDown(rt);
                    if(L < rt->mid())    UpData(rt->lson, L, R, k);
                    if(R > rt->mid())     UpData(rt->rson, L, R, k);
                    PushUp(rt);
                }
        }
        
        long long Query(pionter rt, int L, int R)
            {
                if(L <= rt->l && rt->r <= R)    return rt->val;
                else
                    {
                        if(rt->tag != 0)    PushDown(rt);
                        long long ret = 0;
                        if(L < rt->mid())    ret += Query(rt->lson, L, R);
                        if(R > rt->mid()) ret += Query(rt->rson, L, R);
                        return ret;
                    }
            }
};

int main()
{
    int n, m;
    int x, y, z, ord;
    Segment_Tree tree;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++) scanf("%lld", &tree.a[i]);
    tree.Build(tree.rt, 1, n + 1);
    for(int i = 1; i <= m; i ++)
        {
            scanf("%d", &ord);
            if(ord == 1)
                {
                    scanf("%d%d%d", &x, &y, &z);
                    tree.UpData(tree.rt, x, y + 1, z);
                }
            if(ord ==2)
                {
                    scanf("%d%d", &x, &y);
                    printf("%lld\n", tree.Query(tree.rt, x, y + 1));
                }
        }
    return 0;
}

 

以上是关于自认为自己写的最美的线段树模板的主要内容,如果未能解决你的问题,请参考以下文章

线段树模板 CDOJ1057

线段树模板

P3372 模板线段树 1

P3372 模板线段树 1

[解题报告]P3919 模板可持久化数组(可持久化线段树/平衡树)

线段树模板总结