zoukankan      html  css  js  c++  java
  • 线段树区间和模板

    这是算区间和的线段树的模板

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    #define fori for(i=0;i<n;i++)
    #define fori1 for(i=1;i<=n;i++)
    using namespace std;
    const int maxn = 1e6 + 107;
    #define inf 0x3f3f3f3f
    const int mod = 1e9 + 7;
    
    
    struct node {
        ll l, r;//区间[l,r]
        ll add;//区间的延时标记
        ll sum;//区间和
        ll maxn; //区间最大值
        ll minn; //区间最小值
    }tree[maxn * 4 + 5];//一定要开到4倍多的空间
    
    void pushup(ll rt) {
        tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
        tree[rt].maxn = max(tree[rt << 1].maxn, tree[rt << 1 | 1].maxn);
        tree[rt].minn = min(tree[rt << 1].minn, tree[rt << 1 | 1].minn);
    }
    void pushdown(ll rt) {
        if (tree[rt].add) {
    
            tree[rt << 1].sum += (tree[rt << 1].r - tree[rt << 1].l + 1) * tree[rt].add;
            tree[rt << 1 | 1].sum += (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1) * tree[rt].add;
            tree[rt << 1].maxn += tree[rt].add;
            tree[rt << 1 | 1].maxn += tree[rt].add;
            tree[rt << 1].minn += tree[rt].add;
            tree[rt << 1 | 1].minn += tree[rt].add;
            tree[rt << 1].add += tree[rt].add;
            tree[rt << 1 | 1].add += tree[rt].add;
            tree[rt].add = 0;
    
        }
    }
    void build(ll l, ll r, ll rt) {
        tree[rt].l = l;
        tree[rt].r = r;
        tree[rt].add = 0;//刚开始一定要清0
        if (l == r) {
            cin>>tree[rt].sum;
            tree[rt].minn = tree[rt].maxn = tree[rt].sum;
            return;
        }
        ll mid = (l + r) >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    void updata(ll l, ll r, ll rt, ll val) {
        if (l <= tree[rt].l && r >= tree[rt].r) {
            tree[rt].sum += (tree[rt].r - tree[rt].l + 1) * val;
            tree[rt].minn += val;
            tree[rt].maxn += val;
            tree[rt].add += val;//延时标记
    
            return;
        }
        pushdown(rt);
        ll mid = (tree[rt].l + tree[rt].r) >> 1;
        if (l <= mid) {
            updata(l, r, rt << 1, val);
        }
        if (r > mid) {
            updata(l, r, rt << 1 | 1, val);
        }
        pushup(rt);
    }
    ll querySum(ll l, ll r, ll rt) {
        if (l <= tree[rt].l && r >= tree[rt].r) {
            return tree[rt].sum;
        }
        pushdown(rt);
        ll mid = (tree[rt].l + tree[rt].r) >> 1;
        ll ans = 0;
        ll Max = 0;
        ll Min = inf;
        if (l <= mid) {
            ans += querySum(l, r, rt << 1);
        }
        if (r > mid) {
            ans += querySum(l, r, rt << 1 | 1);
        }
        return ans;
    }
    ll queryMin(ll l, ll r, ll rt) {
        if (l <= tree[rt].l && r >= tree[rt].r) {
            return tree[rt].minn;
        }
        pushdown(rt);
        ll mid = (tree[rt].l + tree[rt].r) >> 1;
        ll ans = 0;
        ll Max = 0;
        ll Min = inf;
        if (l <= mid) {
            Min = min(queryMin(l, r, rt << 1), Min);
        }
        if (r > mid) {
            Min = min(queryMin(l, r, rt << 1 | 1), Min);
        }
        return Min;
    }
    ll queryMax(ll l, ll r, ll rt) {
        if (l <= tree[rt].l && r >= tree[rt].r) {
            return tree[rt].maxn;
        }
        pushdown(rt);
        ll mid = (tree[rt].l + tree[rt].r) >> 1;
        ll ans = 0;
        ll Max = 0;
        ll Min = inf;
        if (l <= mid) {
            Max = max(queryMax(l, r, rt << 1), Max);
        }
        if (r > mid) {
            Max = max(queryMax(l, r, rt << 1 | 1), Max);
        }
     
        return Max;
    }
    int main()
    {
        ll i, j, k;
        ll n, m;
        ll x, y;
        cin >> n >> m;
        build(1, n, 1);
        while (m--)
        {
            ll g;
            cin >> g;
            if (g == 1)
            {
                cin >> x >> y >> k;
                updata(x, y, 1, k);
            }
            if (g == 2)
            {
                cin >> x >> y;
                cout << querySum(x, y, 1) << endl;
            }
        }
    }
  • 相关阅读:
    3D 立体动态图 代码:
    自由切换 网页上的 ico 图标
    ES6 基本语法:
    JavaScript中class类的介绍
    React_01_ECMAScript6
    使用JS计算前一天和后一天
    Web 前端学习计划
    read
    java对象实例化
    关于为什么java需要垃圾回收
  • 原文地址:https://www.cnblogs.com/ch-hui/p/12623865.html
Copyright © 2011-2022 走看看