进阶数据结构应用-一个简单的整数问题2(线段树解法)

目录

题目-一个简单的整数问题2

问题分析

定义线段树需要维护的信息

cpp 复制代码
struct Node {
    int l, r;
    LL sum, add;
};

sum代表考虑当前节点和子节点上的所有标记 的当前区间和, add延迟标记表示给当前区间的所有儿子 都加上add

算法步骤

  • 定义线段树
  • 实现线段树延迟标记更新操作
  • 实现线段树push up操作
  • 实现区间修改操作, 注意要进行懒标记下传
  • 实现区间查询操作, 再查询的时候也需要下传懒标记

代码实现

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N = 1e5 + 10;

int n, m;
LL w[N];
struct Node {
    int l, r;
    LL sum, add;
} tr[N << 2];

void pushup(int u) {
    tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}

void pushdown(int u) {
    Node &ls = tr[u << 1], &rs = tr[u << 1 | 1];
    if (tr[u].add) {
        ls.add += tr[u].add, rs.add += tr[u].add;
        ls.sum += (LL) (ls.r - ls.l + 1) * tr[u].add;
        rs.sum += (LL) (rs.r - rs.l + 1) * tr[u].add;
        tr[u].add = 0;
    }
}

void build(int u, int l, int r) {
    if (l == r) {
        tr[u] = {l, r, w[l], 0};
        return;
    }

    tr[u] = {l, r, 0,0};
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void modify(int u, int ql, int qr, LL val) {
    // 注意区间修改的时候, 需要修改sum和add, 因为add只会作用于子区间
    if (tr[u].l >= ql && tr[u].r <= qr) {
        tr[u].sum += (tr[u].r - tr[u].l + 1) * val;
        tr[u].add += val;
        return;
    }

    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if (ql <= mid) modify(u << 1, ql, qr, val);
    if (qr > mid) modify(u << 1 | 1, ql, qr, val);
    pushup(u);
}

LL query(int u, int ql, int qr) {
    if (tr[u].l >= ql && tr[u].r <= qr) return tr[u].sum;

    LL ans = 0;
    int mid = tr[u].l + tr[u].r >> 1;

    pushdown(u);
    if (ql <= mid) ans += query(u << 1, ql, qr);
    if (qr > mid) ans += query(u << 1 | 1, ql, qr);

    return ans;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= n; ++i) cin >> w[i];

    build(1, 1, n);

    while (m--) {
        char c;
        cin >> c;
        if (c == 'C') {
            int l, r, x;
            cin >> l >> r >> x;
            modify(1, l, r, x);
        }
        else {
            int l, r;
            cin >> l >> r;
            cout << query(1, l, r) << '\n';
        }
    }

    return 0;
}
相关推荐
橘颂TA7 分钟前
【笔试】算法的暴力美学——牛客 BC140:杨辉三角
数据结构·牛客
Lsk_Smion18 分钟前
Hot100(开刷) 之 长度最小的数组--删除倒数第N个链表--层序遍历
java·数据结构·算法·kotlin
luoganttcc19 分钟前
dim3 grid_size(2, 3, 4); dim3 block_size(4, 8, 4)算例
算法
WBluuue27 分钟前
Codeforces 1088 Div1+2(ABC1C2DEF)
c++·算法
像素猎人37 分钟前
map<数据类型,数据类型> mp和unordered_map<数据类型,数据类型> ump的讲解,蓝桥杯OJ4567最大数目
c++·算法·蓝桥杯·stl·map
Narrastory37 分钟前
Note:强化学习(一)
人工智能·算法·强化学习
沐雪轻挽萤1 小时前
1. C++17新特性-序章
java·c++·算法
郝学胜-神的一滴1 小时前
从链表到二叉树:树形结构的入门与核心性质解析
数据结构·c++·python·算法·链表
csdn_aspnet1 小时前
C语言 (QuickSort using Random Pivoting)使用随机枢轴的快速排序
c语言·算法·排序算法
玖釉-1 小时前
深入解析 meshoptimizer:基于 meshopt_computeSphereBounds 的层级包围球构建与 DAG 优化
c++·算法·图形渲染