树状数组理论与实践

目录

  • 1 理论
  • 2 实践
  • 3 参考

1 理论

树状数组(Fenwick Tree),也称为二叉索引树(Binary Indexed Tree, BIT),是一种用于高效计算数组前缀和的数据结构。它可以在 O ( l o g N ) O(logN) O(logN)的时间复杂度下完成单点更新、前缀和查询等操作。

树状数组的主要思想是利用二进制的特性来进行有效的更新和查询。它的核心思想是利用数组的索引来表示树状结构,从而实现高效的查询和更新操作。

具体来说,树状数组的结构如下:

  1. 数组C:这是一个额外的数组,用于存储原始数组的前缀和或其它需要维护的信息。
  2. 每个元素的索引i代表了原始数组中的某个位置。
  3. 每个元素的值C[i]存储了原始数组中某个位置到其父节点(通过某种规则计算)的信息。通常,C[i]的计算规则是将i的二进制表示中最低位的1所代表的区间累加到i上。

lowbit(x)表示数x二进制表示中最后一位1的大小,用十进制表示。

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

例如输入6,返回2;输入7返回1;输入8返回8;输入9返回1。

对于数x,加上lowbit(x)的写法,

//写法1
x += lowbit(x);
//写法2
x += x & -x;

对于数x,减去lowbit(x)的写法,

//写法1
x -= lowbit(x);
//写法2
x -= x & -x;
//写法3
x &= x - 1;

模板题:307区域和检索-数组可修改

C++模板如下,

class Fenwick {vector<int> nums; //下标从1开始,nums[0]无意义vector<int> tree; //tree[i]表示第i个关键区间的元素和。也即数组nums中下标在[i-lowbit(i)+1, i]区间内的元素之和,它的元素个数为lowbit(i)。
public:inline int lowbit(int x) {return x & -x;}Fenwick(vector<int> nums) { this->nums = nums;int n = nums.size();for (int i = 1; i < n; ++i) {add(i, nums[i]); //下标从1开始}return;}//把nums数组中下标i的元素增加了x,更新对应的关键区间元素和tree[k]void add(int i, int x) {for (int k = i + 1; k < tree.size(); k += lowbit(k)) {tree[k] += x;}}//返回nums下标在[1,i]的元素之和,注意是闭区间int get_sum(int i) {int res = 0;for (int k = i; k > 0; k -= lowbit(k)) {res += tree[k];}return res;}//返回下标在[l,r]的元素之和,注意是闭区间int get_sum(int l, int r) {return get_sum(r) - get_sum(l - 1);}};

2 实践

题目1:3072. 将元素分配到两个数组中 II

C++代码如下,

class Fenwick {vector<int> tree;
public:Fenwick(int n) : tree(n) {} //下标从1开始//把下标为i的元素增加1void add(int i) {while (i < tree.size()) {tree[i]++;i += i & -i;}}//返回下标在[1,i]的元素之和,注意是闭区间int pre(int i) {int res = 0;while (i > 0) {res += tree[i];i &= i - 1;}return res;}
};class Solution {
public:vector<int> resultArray(vector<int>& nums) {auto sorted = nums;ranges::sort(sorted);sorted.erase(unique(sorted.begin(), sorted.end()), sorted.end());int m = sorted.size();vector<int> a{nums[0]}, b{nums[1]};Fenwick t1(m + 1), t2(m + 1); //t1,t2是树状数组t1.add(ranges::lower_bound(sorted, nums[0]) - sorted.begin() + 1); //+1是因为下标从1开始t2.add(ranges::lower_bound(sorted, nums[1]) - sorted.begin() + 1); //+1是因为下标从1开始for (int i = 2; i < nums.size(); ++i) {int x = nums[i];int v = ranges::lower_bound(sorted, x) - sorted.begin() + 1;int gc1 = a.size() - t1.pre(v);int gc2 = b.size() - t2.pre(v);if (gc1 > gc2 || gc1 == gc2 && a.size() <= b.size()) {a.push_back(x);t1.add(v);} else {b.push_back(x);t2.add(v);}}a.insert(a.end(), b.begin(), b.end());return a;}
};

题目2

3 参考

  1. 带你发明树状数组!附数学证明(Python/Java/C++/Go/JS/Rust)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux报错排查-刚安装好的ubuntu系统无法ssh连接

Linux运维工具-ywtool 目录 一.问题描述二.问题解决2.1 先给ubuntu系统配置阿里云源2.2 安装openssh-server软件2.3 在尝试ssh连接,可以连接成功了 三.其他命令 一.问题描述 系统:ubuntu-18.04-desktop-amd64 系统安装完后,想要通过xshell软件连接系统,发现能Ping通系统的IP,但…

三色标记过程

可达性分析 GC过程中需要对对象图遍历做可达性分析。使用了三色标记法进行分析。 什么三色&#xff1f; 白色&#xff1a;尚未访问过。 黑色&#xff1a;本对象已访问过&#xff0c;而且本对象 引用到 的其他对象 也全部访问过了。 灰色&#xff1a;本对象已访问过&#xff0…

C语言第三十七弹---文件操作(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 文件操作 1、文件的随机读写 1.1、fseek 1.2、ftell 1.3、rewind 2、文件读取结束的判定 2.1、被错误使用的 feof 3、文件缓冲区 总结 1、文件的随机读写…

根据QQ号获取暗恋的人的全部歌单

文章目录 前言一、成果展示二、后端开发流程三、前后端障碍与难点解决四、待扩展内容五、总结 前言 本人喜欢使用QQ音乐听歌&#xff0c;并且喜欢点击好友栏目观看最近在听&#xff0c;了解暗恋的人最近在听什么歌曲&#xff0c;知己知彼&#xff0c;百战不殆。但是每次都需要…

XSS-Labs靶场1---11关

一、XSS环境搭建&#xff1a; [ 靶场环境篇 ] XSS-labs 靶场环境搭建(特别详细)_xss靶场搭建-CSDN博客 &#xff08;该博主总结的较为详细&#xff0c;若侵权必删&#xff09; 常用的xss攻击语句&#xff1a; 输入检测确定标签没有过滤后&#xff0c;为了显示存在漏洞&#…

js如何显示input输入的文字的个数

一、直接上效果图 二、直接上代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><div class"fabu"><input type"text" id"contact" on…

python的generator生成器用法测试

yield、send、threw、close # coding: utf8# 生成器 def gen(n):for i in range(n):yield ig gen(5) # 创建一个生成器 print(g) # <generator object gen at 0x10bb46f50> print(type(g)) # <type generator># 迭代生成器中的数据(只有执行for循环…

tvm android_rpc_test.py执行报错解决

执行 python3 tests/android_rpc_test.py 报错&#xff1a; Run CPU test ... Traceback (most recent call last): File "tests/android_rpc_test.py", line 129, in <module> test_rpc_module() File "tests/android_rpc_test.py", line …

go语言添加代理

LiteIDE 工具->管理 https://mirrors.aliyun.com/goproxy/或https://goproxy.cn,direct 命令行 go env -w GOPROXYhttps://goproxy.cn,direct

基于SpringBoot的CNKI数据精炼与展示

目 录 摘 要 I Abstract II 引 言 1 1 相关技术 3 1.1 SpringBoot框架 3 1.1.1 Spring框架介绍 3 1.1.2 SpringBoot框架介绍 3 1.2 MyBatis框架 4 1.3 Echarts框架 5 1.4 Bootstrap框架 5 1.5 JQuery技术 6 1.6 本章小结 6 2 系统分析 7 2.1 功能需求分析 7 2.1.1 门户模块需求…

【论文笔记】Scalable Diffusion Models with State Space Backbone

原文链接&#xff1a;https://arxiv.org/abs/2402.05608 1. 引言 主干网络是扩散模型发展的关键方面&#xff0c;其中基于CNN的U-Net&#xff08;下采样-跳跃连接-上采样&#xff09;和基于Transformer的结构&#xff08;使用自注意力替换采样块&#xff09;是代表性的例子。…

学习Android的第二十六天

目录 Android Gesture 手势 Android 中手势交互的执行顺序 GestureListener SimpleOnGestureListener 范例 参考文档 Android Gesture 手势添加与识别 使用GestureLibraries 范例 参考文档 Android Gesture 手势 手势操作在现代移动应用中扮演了非常重要的角色&…

【动态规划入门】不同的子序列

每日一道算法题之不同的子序列 一、题目二、思路三、C代码 一、题目 题目来源&#xff1a;LeetCode【难度&#xff1a;困难】 给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 109 7 取模。 示例如下&#xff1a; 输入&…

数据结构(二)——线性表(单链表)

2.3线性表的链式表示 顺序表的优缺点&#xff1a; 优点&#xff1a;可随机存储&#xff0c;存储密度高 缺点&#xff1a;要求大片连续空间&#xff0c;且改变容量不方便 2.3.1 单链表的基本概念 单链表&#xff1a;用链式存储实现了线性结构。一个结点存储一个数据元素&…

【IEEE列表会议】IEEE第三届信息与通信工程国际会议国际会议(JCICE 2024)

会议简介 Brief Introduction 2024年第三届信息与通信工程国际会议国际会议 (JCICE 2024) 会议时间&#xff1a;2024年5月10日-12日 召开地点&#xff1a;中国福州 大会官网&#xff1a;JCICE 2024-2024 International Joint Conference on Information and Communication Engi…

高电平复位电路工作原理详解

单片机复位电路的作用是&#xff1a;使单片机恢复到起始状态&#xff0c;让单片机的程序从头开始执行&#xff0c;运行时钟处于稳定状态、各种寄存器、端口处于初始化状态等等。目的是让单片机能够稳定、正确的从头开始执行程序。一共分为&#xff1a;高电平复位&#xff0c;低…

程序员失业,被迫开启 PlanB——成为自由职业/独立开发者的第 0 天

程序员失业&#xff0c;被迫开启 PlanB——成为自由职业/独立开发者的第 0 天 今天在逛V2EX的时候看到的一个帖子&#xff0c;程序员中年被裁&#xff0c;被迫开启独立开发这条路。 原贴如下&#xff1a; lastday, 失业啦 公司年前通知我合同到期不续签&#xff0c;今天是我…

docker学习进阶

一、dockerfile解析 官方文档&#xff1a; Dockerfile reference | Docker Docs 1.1、dockfile是什么&#xff1f; dockerfile是用来构建docker镜像的文本文件&#xff0c;由一条条构建镜像所需的指令和参数构成的脚本。 之前我们介绍过通过具体容器反射构建镜像(docker comm…

JavaWeb - 3 - JavaScript(JS)

JavaScript(JS)官方参考文档&#xff1a;JavaScript 教程 JavaScript&#xff08;简称&#xff1a;JS&#xff09;是一门跨平台、面向对象的脚本语言&#xff0c;是用来控制网页行为的&#xff0c;它能使网页可交互&#xff08;脚本语言就不需要编译&#xff0c;直接通过浏览器…

Luajit 2023移动版本编译 v2.1.ROLLING

文章顶部有编好的 2.1.ROLLING 2023/08/21版本源码 Android 64 和 iOS 64 luajit 目前最新的源码tag版本为 v2.1.ROLLING on Aug 21, 2023应该是修正了很多bug, 我是出现下面问题才编的. cocos2dx-lua 游戏 黑屏 并报错: [LUA ERROR] bad light userdata pointer 编…