【模板】树状数组

目录:

单点修改,区间查询:

        题目描述:

        lowbit()运算:

        插入、修改单点数据:

        计算前缀和:

        完整代码:

区间修改,单点查询:

        计算差分数组:

        计算每个点的值:

        完整代码:


单点修改,区间查询:


题目描述:

如题,已知一个数列,你需要进行下面两种操作:

  • 将某一个数加上 x

  • 求出某区间每一个数的和

输入格式

第一行包含两个正整数 n, m,分别表示该数列数字的个数和操作的总个数。

第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。

接下来 m 行每行包含 3 个整数,表示一个操作,具体如下:

  • 1 x k 含义:将第 x 个数加上 k

  • 2 x y 含义:输出区间 [x, y] 内每个数的和

输出格式

输出包含若干行整数,即为所有操作 2 的结果。

lowbit()运算:

//非负整数n在二进制表示下最低位1及其后面的0构成的数值
//eg.lowbit(12) = lowbit((1100)2) = (100)2 = 4
//将1100按位取反后加一得到0100,会发现除了最低位的一和后面的零,其余位上与原数均相反
//故两者按位与后正好得到最低位1及其后面的0构成的数值
//又取反加一为补码,故lowbit为k & -k
int lowbit(int k) {
    return k & -k;
}

 插入、修改单点数据:

//如图:
//tree[x]保存以x为根的子树中叶节点值的和
//将x转化为二进制后,发现每一层的末尾的零的个数都相同
//且tree[x]覆盖的长度即为lowbit(x)的值
//tree[x]的父节点为tree[x + lowbit(x)]
void add(int x, int k) {
    while(x <= n) {
        tree[x] += k;
        x += lowbit(x);
    }
}

计算前缀和:

//由图可知,若求前7项的和,则该值为tree[7] + tree[6] + tree[4]
//故,通过循环可以求出结果
int sum(int x) {
    int ans = 0;
    while(x != 0) {
        ans += tree[x];
        x -= lowbit(x);
    }
    return ans;
}

完整代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, m, a, flag, p, q, tree[N];

int lowbit(int k) {
    return k & -k;
}

void add(int x, int k) {
    while(x <= n) {
        tree[x] += k;
        x += lowbit(x);
    }
}

int sum(int x) {
    int ans = 0;
    while(x != 0) {
        ans += tree[x];
        x -= lowbit(x);
    }
    return ans;
}

int main() {
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &a);
        add(i, a);
    }
    for(int i = 1; i <= m; ++i) {
        scanf("%d %d %d", &flag, &p, &q);
        if(flag == 1)
            add(p, q);
        else
            printf("%d\n", sum(q) - sum(p - 1));
    }
    return 0;
}

区间修改,单点查询:


计算差分数组:

//与单点修改、区间查询类似
void add(int x, int k) {
    while(x <= n) {
        tree[x] += k;
        x += lowbit(x);
    }
}

计算每个点的值:

//与单点修改、区间查询类似
//此时计算的结果为每个点的值
int query(int x) {
    int ans = 0;
    while(x != 0) {
        ans += tree[x];
        x -= lowbit(x);
    }
    return ans;
}

完整代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, m, now, last, flag, p, q, num, tree[N];

int lowbit(int k) {
    return k & -k;
}

void add(int x, int k) {
    while(x <= n) {
        tree[x] += k;
        x += lowbit(x);
    }
}

int query(int x) {
    int ans = 0;
    while(x != 0) {
        ans += tree[x];
        x -= lowbit(x);
    }
    return ans;
}

int main() {
    scanf("%d %d", &n, &m);
    //计算差分数组,将相差的值放入数组中
    //eg.原本的数组应为a[] = {1, 6, 8, 5, 10}
    //则差分数组应为b[] = {1, 5, 2, -3, 5}
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &now);
        add(i, now - last);
        last = now;
    }
    for(int i = 1; i <= m; ++i) {
        scanf("%d", &flag);
        //若要修改区间[p, q]的值
        //例如上述举的例子,若要将区间[2, 4]均加上3
        //则原数组变为a[] = {1, 9, 11, 8, 10}
        //差分数组变为b[] = {1, 8, 2, -3, 2}
        //即对差分数组来说只需修改下标为p的值,和下标为q + 1的值
        if(flag == 1) {
            scanf("%d %d %d", &p, &q, &num);
            add(p, num);
            add(q + 1, -num);
        }
        //若查询某个点的值
        //前p个差分数组的值相加即为该点的值
        //与单点修改、区间查询中的求前缀和类似
        else {
            scanf("%d", &p);
            printf("%d\n", query(p));
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/4899.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Node.js 入门

转载请注明出处&#xff0c;点击此处 查看更多精彩内容。 什么是 Node.js &#xff1f; Node.js 是一个基于 Chrome V8 引擎的开源的跨平台的 JavaScript 运行时环境。 Node.js 采用了基于事件的、单线程的异步 I/O 架构。 Node.js 的组成部分 V8引擎 V8 引擎就是 JavaScrip…

使用 React 和 GPT-4 技术构建智能语言翻译应用

Midjourney 创作&#xff0c;Language Translation in future在今天的互联世界中&#xff0c;语言翻译在弥合沟通差距和促进全球合作方面发挥着至关重要的作用。随着像 OpenAI 的 GPT-4 这样先进的 AI 模型的出现&#xff0c;我们现在有机会创建高度精确和上下文感知的翻译工具…

USB键盘实现——带指示灯的键盘(九)

文章目录带指示灯的键盘set_report 类特殊请求实现类特殊请求USB 控制端点收到的数据增加一个输出端点实现配置描述符集合输出端点收到的数据带指示灯的键盘 要实现带指示灯的键盘&#xff0c;有两种方式 除控制端点和输入端点外&#xff0c;不额外增加端点&#xff0c;根据 …

不完全微分算法(SCL+ST代码)

PID控制器的基本算法,可以参看专栏的系列文章,链接如下: 三菱FX3U PLC 位置式PID算法(ST语言)_fx3u pid_RXXW_Dor的博客-CSDN博客三菱PLC自带的PID不必多说,大家可以自行查看指令说明。关于FX3U 增量式PID可以参看专栏的另一篇博客三菱PLC增量式PID算法FB(带死区设置和外部…

springCloud学习【3】之Docker完整版

文章目录一 初识Docker1.1 应用部署的环境问题1.2 Docker简介1.3 Docker解决操作系统环境差异1.4 Docker和虚拟机的区别1.5 Docker架构1.5.1 镜像和容器1.5.2 DockerHub1.5.3 Docker架构1.5.4 Docker工作流1.6 Docker的安装和启动1.7 安装步骤1.8 启动Docker1.9 配置镜像加速二…

总结802

早上&#xff1a; 6:23起床 6:43出门 7:00~7:40小湖读书 8:00~9:45机器人控制 9:50~11:30句句真研 11:31~12:10吃饭 12:12~12:22动漫 12:45~2:09午觉 2:00~4:15深度学习 4:26~4:39去图书馆 4:40~6:11高等数学第五讲 6:13~6:40跑步开合跳100胯下击掌100 6:50~7:20吃…

PS基础操作-抠图与导出-学习记录

目录 注&#xff1a;PS版本为2022&#xff0c;有个智能对象选择功能比较方便抠图 第一步&#xff1a;导入图像文件 第二步&#xff1a;基础的画布界面移动 鼠标滚轮上下滑动&#xff0c;可以是上下滚动界面 按住ctrl鼠标滚轮&#xff0c;可以左右滚动界面 按住alt鼠标滚轮…

华为OD机试题,用 Java 解【快递货车】问题 | 含解题说明

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:快递货车 题目 一辆运送快递的…

【python刷题】LeetCode 2057E 值相等的最小索引(5种简单高效的解法)

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于海外某世界知名高校就读计算机相关专业。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。…

问答ChatGPT-4:探索未来微数据中心IDC的发展趋势

从去年年底开始到现在&#xff0c;大众对以ChatGPT-4为主的人工智能AI的话题讨论盛况空前。这是一款由OpenAI发布的聊天机器人模型&#xff0c;一经上线&#xff0c;短短5天完成100万用户积累&#xff0c;并在最近实现月活用户破亿。实际上&#xff0c;ChatGPT和智能客服、智能…

CN RedGolf 集团利用 KEYPLUG 后门攻击 Windows 和 Linux 系统

被追踪为 RedGolf 的 CN 国家支持的威胁活动组织被归因于使用名为 KEYPLUG 的自定义 Windows 和 Linux 后门。 Recorded Future 告诉 The Hacker News&#xff1a;“RedGolf 是一个特别多产的CN国家支持的威胁组织&#xff0c;可能多年来一直活跃于全球范围内的广泛行业。” …

HandlerInterceptor拦截器的原理

是什么 HandlerInterceptor拦截的是请求&#xff0c;是springMVC项目中的拦截器&#xff0c;它拦截的目标是请求的地址。也就是说&#xff0c;它可以对请求进行拦截处理&#xff0c;所有实现了HandlerInterceptor&#xff0c;并且进行了配置的的类&#xff0c;都有这个能力&am…

第四章 共享模型之 管程 (下)

JUC并发编程系列文章 http://t.csdn.cn/UgzQi 文章目录JUC并发编程系列文章前言七、wait -- notify1、为什么使用 wait2、 wait -- notify 原理3、API 介绍八、wait -- notify 的正确姿势示例一&#xff1a;sleep会拿着锁睡觉&#xff0c;阻碍其它线程执行示例二&#xff1a;wa…

Eyeshot 2023 重大变化--2023版本将被Crack

Eyeshot 2023是一个基于 Microsoft .NET Framework 的 CAD 控件。它允许开发人员快速将 CAD 功能添加到 WinForms 和 WPF 应用程序。Eyeshot 提供了从头开始构建几何体、使用有限元方法对其进行分析并在其上生成刀具路径的工具。还可以使用 CAD 交换文件格式导入或导出几何图形…

操作系统页表

虚拟内存 虚拟地址到物理地址的映射以实现隔离性 每个程序有独立的地址空间&#xff0c;不相互影响 页表 地址操作简单流程 CPU向虚拟地址va加载或写入数据–>CPU将va交给内存管理单元MMU–>SATP寄存器存放着内存中存放虚拟地址到物理地址的表单–>MMU通过SATP查找…

03_C++函数

函数的分文件编写1.1头文件-函数声明//swap.h文件 #include<iostream> using namespace std;void swap(int a, int b);1.2源文件-函数定义在源文件中&#xff0c;要加上头文件引用#include "swap.h"//swap.cpp文件 #include "swap.h"void swap(int a…

最少砝码(思维+找规律)

最少砝码 前n个可以表示0~k; 第n1个为x&#xff08;x>k&#xff09;; 最大可测maxnkx; 第n1个和前n个放两边 可测得x-k&#xff1b; 让x-kk1&#xff0c;得到x2k1&#xff1b; maxn3k1&#xff1b; k1 可以用(2k1) - (k-0) 表示 k2 可以用(2k1) - (k-1) 表示 … 2k1 可以用…

Compose 动画 (八) : Compose中的动画差值器 AnimationSpec

1. AnimationSpec是什么 Android Compose中的AnimationSpec用来自定义动画规格。 啥意思呢&#xff0c;其实就是类似于传统View体系中的差值器Interpolator&#xff0c;但是比起差值器&#xff0c;又提供了更多的功能。 根据其不同的子类&#xff0c;可以来控制动画执行时长、…

运维1.12了解集中式日志管理工具 ELK 的基本用法,包括数据采集、搜索和展示

ELK 是一个由三个开源项目组成的日志管理工具&#xff0c;它们分别是 Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一个基于 Lucene 的搜索引擎&#xff0c;它可以提供实时的分布式搜索和分析能力&#xff1b;Logstash 是一个日志收集和处理工具&#xff0c;可以实现多…

《白帽子讲Web安全》世界观安全

1.Web安全简史1.1中国黑客简史对于现代计算机系统来说&#xff0c;在用户态的最高权限是root&#xff0c;也是黑客们最渴望能够获取的系统最高权限。不想拿到“root”的黑客&#xff0c;不是好黑客。在现实世界中&#xff0c;真正造成破坏的&#xff0c;往往并非那些挖掘并研究…