热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

线段树区间更新与查询

本文介绍了如何使用线段树实现区间加法和区间查询操作,包括详细的代码实现和解释。

线段树是一种高效的数据结构,常用于处理区间更新和查询问题。本文将详细介绍如何使用线段树实现区间加法和区间查询操作。

首先,我们需要包含一些必要的头文件,并定义一些基本的宏和变量:

#include 
#include 
#include 
#include 
#include 
#include 

#define LL long long
#define l(x) (x <<1)
#define r(x) ((x <<1) | 1)

using namespace std;

struct Tree {
    LL sum, tag;
} Tr[500100];

LL a[500100];

接下来,我们定义一个更新函数,用于更新节点的值:

void update(LL id) {
    Tr[id].sum = Tr[l(id)].sum + Tr[r(id)].sum;
}

然后,定义一个下推函数,用于将懒标记传递给子节点:

void pushdown(LL l, LL r, LL id) {
    Tr[r(id)].tag += Tr[id].tag;
    Tr[l(id)].tag += Tr[id].tag;
    Tr[id].sum += (r - l + 1) * Tr[id].tag;
    Tr[id].tag = 0;
}

接下来是构建线段树的函数:

void build(LL l, LL r, LL id) {
    if (l == r) {
        Tr[id].sum = a[l];
        return;
    }
    LL mid = (l + r) / 2;
    build(mid + 1, r, r(id));
    build(l, mid, l(id));
    update(id);
}

定义一个区间加法函数,用于在指定区间内增加一个值:

void add(LL al, LL ar, LL x, LL l, LL r, LL id) {
    if (l > ar || r = al) add(al, min(mid, ar), x, l, mid, l(id));
    if (mid 

最后,定义一个区间查询函数,用于查询指定区间的和:

LL query(LL al, LL ar, LL l, LL r, LL id) {
    if (l > r) return 0LL;
    if (al == l && ar == r) {
        return Tr[id].tag * (r - l + 1) + Tr[id].sum;
    }
    pushdown(l, r, id);
    LL mid = (r + l) / 2;
    LL t = 0;
    if (mid >= al) t += query(al, min(mid, ar), l, mid, l(id));
    if (mid 

主函数部分,读取输入并进行相应的操作:

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    build(1, n, 1);
    while (m--) {
        int cas;
        scanf("%d", &cas);
        if (cas == 1) {
            LL x, y, k;
            scanf("%lld%lld%lld", &x, &y, &k);
            add(x, y, k, 1, n, 1);
        } else {
            LL x, y;
            scanf("%lld%lld", &x, &y);
            printf("%lld\n", query(x, y, 1, n, 1));
        }
    }
    return 0;
}

以上就是使用线段树实现区间加法和区间查询的完整代码。希望对大家有所帮助。


推荐阅读
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本文探讨了C++编程中理解代码执行期间复杂度的挑战,特别是编译器在程序运行时生成额外指令以确保对象构造、内存管理、类型转换及临时对象创建的安全性。 ... [详细]
  • ListView简单使用
    先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ... [详细]
  • 本文详细介绍了get和set方法的作用及其在编程中的实现方式,同时探讨了点语法的使用场景。通过具体示例,解释了属性声明与合成存取方法的概念,并补充了相关操作的最佳实践。 ... [详细]
  • 本文详细介绍了 Android 开发中 layout_gravity 属性的使用方法及其在不同布局下的效果,旨在帮助开发者更好地理解和利用这一属性来精确控制视图的布局。 ... [详细]
  • 编写css让div2在div1的右下角? ... [详细]
  • Python notes
    6.1.1.执行模块当你用下面的方式运行一个Python模块pythonfibo.py模块中的代码将会被执行,就像导入它一样,不过此时__name__被设置为__main__。 ... [详细]
  • 使用JS、HTML5和C3创建自定义弹出窗口
    本文介绍如何结合JavaScript、HTML5和C3.js来实现一个功能丰富的自定义弹出窗口。通过具体的代码示例,详细讲解了实现过程中的关键步骤和技术要点。 ... [详细]
  • 本篇文章介绍如何将两个分别表示整数的链表进行相加,并生成一个新的链表。每个链表节点包含0到9的数值,如9-3-7和6-3相加得到1-0-0-0。通过反向处理链表、逐位相加并处理进位,最终再将结果链表反向,即可完成计算。 ... [详细]
  • 本文详细介绍了如何解决 Microsoft SQL Server 中用户 'sa' 登录失败的问题。错误代码为 18470,提示该帐户已被禁用。我们将通过 Windows 身份验证方式登录,并启用 'sa' 帐户以恢复其访问权限。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 本文介绍了如何通过在数据库表中增加一个字段来记录文章的访问次数,并提供了一个示例方法用于更新该字段值。 ... [详细]
  • 解决Spring Boot项目创建失败的问题
    在尝试创建新的Spring Boot项目时遇到了一些问题,具体表现为在项目创建过程中的两个关键步骤出现错误。本文将详细探讨这些问题及其解决方案。 ... [详细]
  • 一个登陆界面
    预览截图html部分123456789101112用户登入1314邮箱名称邮箱为空15密码密码为空16登 ... [详细]
  • Shell脚本中变量操作详解
    本文基于《鸟哥的Linux私房菜》一书,详细介绍了Shell脚本中变量的使用方法,包括变量的赋值规则、字符串处理技巧以及环境变量的管理等,旨在帮助读者更好地理解和使用Shell中的变量。 ... [详细]
author-avatar
dishonest的你_507
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有