博客
关于我
POJ3468(A Simple Problem with Integers)
阅读量:211 次
发布时间:2019-02-28

本文共 2541 字,大约阅读时间需要 8 分钟。

线段树是一个高效的数据结构,能够在O(log n)的时间复杂度内完成区间更新和查询操作。对于这个问题,我们需要处理两种操作:区间加法和区间求和。线段树的懒标记机制可以帮助我们高效地处理这些操作。

思路总结

  • 线段树结构:我们使用线段树来处理区间操作。每个节点表示一个区间,叶子节点对应数组中的单个元素。

  • 懒标记:懒标记用于记录对子节点的更新操作,避免在每次查询时都遍历整个树,从而提高效率。

  • 区间更新:对于“C a b c”操作,我们通过线段树更新区间[a, b]中的每个元素c,并使用懒标记记录这些更新操作。

  • 区间查询:对于“Q a b”操作,我们通过线段树查询区间[a, b]的和,并返回结果。

  • 输入处理:使用高效的输入读取方法,避免因读取速度慢而导致超时。

  • 解决代码

    #include 
    #include
    #include
    #include
    #include
    #include
    using namespace std;#define ll long long#define maxn 100002#define lson(k) k << 1#define rson(k) k << 1 | 1#define build(k, l, r) build(k, l, r)#define push_down(k, l, r) push_down(k, l, r)struct SegmentTree { ll *a, *s, *lazy; int size; SegmentTree(int n) : size(1) { while (size < n) size <<= 1; a = new ll[size << 1]; s = new ll[size << 1]; lazy = new ll[size << 1](); fill(a + size, a + size + n, 0); } void build(int k, int l, int r) { if (l == r) { s[k] = a[k + size]; return; } int m = lson(k); build(m, l, mid); build(rson(k), mid + 1, r); s[k] = s[m] + s[rson(k)]; } void push_down(int k, int l, int r) { if (lazy[k]) { lazy[lson(k)] += lazy[k]; lazy[rson(k)] += lazy[k]; int m = (l + r) >> 1; s[lson(k)] += (m - l) * lazy[k]; s[rson(k)] += (r - m) * lazy[k]; lazy[k] = 0; } } void update(int k, int l, int r, int ql, int qr, ll val) { push_down(k, l, r); if (ql > r || qr < l) return; if (ql <= l && r <= qr) { lazy[k] += val; s[k] += (r - l + 1) * val; return; } int m = (l + r) >> 1; update(lson(k), l, m, ql, qr, val); update(rson(k), m + 1, r, ql, qr, val); s[k] = s[lson(k)] + s[rson(k)]; } ll query(int k, int l, int r, int ql, int qr) { push_down(k, l, r); if (ql > r || qr < l) return 0; if (ql <= l && r <= qr) return s[k]; int m = (l + r) >> 1; return query(lson(k), l, m, ql, qr) + query(rson(k), m + 1, r, ql, qr); }};int main() { int t, n, q; scanf("%d %d", &t, &n); while (t--) { SegmentTree st(n); for (int i = 0; i < n; ++i) scanf("%lld", &st.a[size + i]); st.build(1, 1, n); for (int i = 0; i < q; ++i) { char op[5]; int a, b, c; scanf("%s", op); if (op[0] == 'Q') { scanf("%d %d", &a, &b); a = a < 1 ? 1 : a; b = b > n ? n : b; ll res = st.query(1, 1, n, a, b); printf("%lld\n", res); } else { scanf("%d %d %d", &a, &b, &c); a = a < 1 ? 1 : a; b = b > n ? n : b; st.update(1, 1, n, a, b, c); } } } return 0;}

    代码解释

  • 线段树结构:使用数组a存储原始数据,s存储线段树节点的值,lazy存储懒标记。

  • 构建函数:递归构建线段树,合并左右子节点的值。

  • 懒标记推送:将懒标记传播到子节点,更新子节点的值。

  • 区间更新:递归更新指定区间的值,并使用懒标记记录更新操作。

  • 区间查询:递归查询指定区间的和,并返回结果。

  • 输入处理:读取输入数据,初始化线段树,处理每个操作并输出结果。

  • 该实现确保了线段树的高效性,能够在较短的时间内处理大量操作,适用于大规模数据的区间操作问题。

    转载地址:http://szrp.baihongyu.com/

    你可能感兴趣的文章
    NI笔试——大数加法
    查看>>
    NLog 自定义字段 写入 oracle
    查看>>
    NLP 基于kashgari和BERT实现中文命名实体识别(NER)
    查看>>
    NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器
    查看>>
    NLP_什么是统计语言模型_条件概率的链式法则_n元统计语言模型_马尔科夫链_数据稀疏(出现了词库中没有的词)_统计语言模型的平滑策略---人工智能工作笔记0035
    查看>>
    NLP学习笔记:使用 Python 进行NLTK
    查看>>
    NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估
    查看>>
    NLP:使用 SciKit Learn 的文本矢量化方法
    查看>>
    Nmap扫描教程之Nmap基础知识
    查看>>
    Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
    查看>>
    NMAP网络扫描工具的安装与使用
    查看>>
    NMF(非负矩阵分解)
    查看>>
    NN&DL4.1 Deep L-layer neural network简介
    查看>>
    NN&DL4.3 Getting your matrix dimensions right
    查看>>
    NN&DL4.8 What does this have to do with the brain?
    查看>>
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    查看>>
    NO 157 去掉禅道访问地址中的zentao
    查看>>
    No Datastore Session bound to thread, and configuration does not allow creation of non-transactional
    查看>>
    No fallbackFactory instance of type class com.ruoyi---SpringCloud Alibaba_若依微服务框架改造---工作笔记005
    查看>>
    No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalanc
    查看>>