[swift刷题模板] 树状数组(BIT/FenwickTree)

news/2024/7/20 22:08:12 标签: swift, 开发语言, ios

@[TOC]([swift刷题模板] 树状数组(BIT/FenwickTree) )

一、 算法&数据结构

1. 描述

  • [python刷题模板] 树状数组

在这里插入图片描述

二、 模板代码

1. 单点赋值(增加),区间求和(PURQ)

例题: 307. 区域和检索 - 数组可修改

swift">class BIT {
    var c: [Int]
    var n: Int 
    init(_ n: Int){
        c = Array(repeating:0, count: n + 1)
        self.n = n 
    }
    func add(_ i: Int, _ v: Int){
        var i = i 
        while i <= n {
            c[i] += v 
            i += i & -i 
        }
    }
    func sum(_ i: Int) -> Int {
        var i = i 
        var s = 0 
        while i > 0 {
            s += c[i] 
            i &= i - 1
        }
        return s
    }
}

class NumArray {
    let tree: BIT 
    var nums: [Int]
    init(_ nums: [Int]) {        
        tree = BIT(nums.count + 1)
        self.nums = nums 
        for (i, v) in nums.enumerated() {
            tree.add(i + 1, v)
        }
    } 
    func update(_ index: Int, _ val: Int) {
        tree.add(index+1, val - nums[index])
        nums[index] = val
    }
    
    func sumRange(_ left: Int, _ right: Int) -> Int {
        return tree.sum(right + 1) - tree.sum(left)        
    }
}

  • 以下待施工

2. 区间更新,单点询值(RUPQ)

例题: 1589. 所有排列中的最大和
这题其实应该用差分数组,可以省一层log。思想就是树状数组的IUPQ模型。

树状数组经典案例,要用差分数组理解:
这个实际上是用树状数组维护原数组的差分数组c[i]=a[i]-a[i-1]
求原数组的值a[i]实际上是差分数组的前缀sum(c[0]…c[i]),所以get a[i]可以用sum c[i]表示,
而原数组a区间[x,y]更新+v,产生的效果是:x位置比x-1位置大了v,y+1位置比y小了v;
对差分数组c来说,产生变化的就是c[x]增加了v,c[y+1]减小了v,因为c数组代表的是a中每个数比前一个数的差。

  • sum[i]代替get[i],单点求值
  • 两步add(l,v)和add(r+1,-v),区间更新

3.区间更新,区间求和(RURQ)

题目: P3372 【模板】线段树 1

  • 记sigma(r,i)表示r数组的前i项和。
  • 我们知道,在区间求和的BIT中,实际维护了原数组a的差分数组d。
  • 于是有a[n] = d[1]+d[2]+…+d[n]
  • 观察式子:
    a[1]+a[2]+…+a[n]
    = (d[1]) + (d[1]+d[2]) + … + (d[1]+d[2]+…+d[n])
    = n * d[1] + (n-1) * d[2] +… +d[n]
    = n * (d[1]+d[2]+…+d[n]) - (0 * d[1]+1 * d[2]+…+(n-1) * d[n]) (式子①)
    维护一个数组d2[n],其中d2[i] = (i-1)*d[i]
    每当修改c的时候,就同步修改一下d2,这样复杂度就不会改变

那么 sigma(a,n) = 式子①=n*sigma(d,n) - sigma(d2,n)

5. 单点更新区间求极值

例题: CF522 D. Closest Equals
这是20220923的茶。

  • 相同元素组成可以看成线段,问题转化为求区间内最短线段。
  • 询问离线,按r排序,计算每个线段长度,记在左端点上。
  • 查询区间最小值即可。
  • 正常用线段树,但是py线段树过不了,于是上网查了个树状数组的模板

6. 单点赋值,区间询问最大(LIS II)

例题: 2407. 最长递增子序列 II
周赛T4,当时用线段树做的;实际测试线段树的表现甚至优于树状数组,奇怪极了。

7. 二维树状数组(IUPQ)

例题: 6292. 子矩阵元素加 1

  • 周赛T2,这题卡一维树状数组;但是可以差分过;可以二维树状数或二维差分过。

http://www.niftyadmin.cn/n/5111425.html

相关文章

正则表达式[总结]

文章目录 1. 为什么要学习正则表达式2. 再提出几个问题&#xff1f;3. 解决之道-正则表达式4. 正则表达式基本介绍5. 正则表达式底层实现(重要)6. 正则表达式语法6.1 基本介绍6.2 元字符(Metacharacter)-转义号 \\\6.3 元字符-字符匹配符6.4 元字符-选择匹配符6.5 元字符-限定符…

Kotlin中的嵌套类、内部类、枚举类、密封类、数据类、单例类、伴生对象

在Kotlin中&#xff0c;类可以分为以下几种类型&#xff0c;并使用样例代码进行说明&#xff1a; 嵌套类&#xff08;Nested Class&#xff09;&#xff1a;嵌套类是指可以嵌套在其他类中的类。嵌套类不能直接访问外部类的成员。例如&#xff0c;在下面的代码中&#xff0c;&q…

【Java】ListIterator

列表迭代器&#xff1a; ListIterator listIterator()&#xff1a;List 集合特有的迭代器该迭代器继承了 Iterator 迭代器&#xff0c;所以&#xff0c;就可以直接使用 hasNext()和next()方法。特有功能&#xff1a; Object previous()&#xff1a;获取上一个元素boolean hasPr…

基于鱼鹰优化的BP神经网络(分类应用) - 附代码

基于鱼鹰优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于鱼鹰优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.鱼鹰优化BP神经网络3.1 BP神经网络参数设置3.2 鱼鹰算法应用 4.测试结果&#xff1a;5.M…

卫星结构。。。

• 下图介绍了现代卫星中常见的组件&#xff0c;它们被分为 卫星有效载荷 和 卫星总线 。 – 卫星有效载荷 包括任务专用设备&#xff0c;例如用于地球观测的高分辨率相机或用于电信的强大无线电硬件。 – 卫星总线 包括操作和维护卫星所需的所有组件。 • 它被设计为独立于有效…

异步为什么会造成 HTTP 队首阻塞?

一、http 协议的队首阻塞 队首阻塞,队首的事情没有处理完的时候&#xff0c;后面的都要等着。 1.1 HTTP1.0 的队首阻塞 对于同一个 tcp 连接&#xff0c;所有的 http1.0 请求放入队列中&#xff0c;只有前一个请求的响应收到了&#xff0c;然后才能发送下一个请求。http1.0 的…

FFmpeg工具使用集

FFmpeg工具使用集 About FFmpeg Java调用FFmpeg FFmpeg 工具&#xff1a; FFMPEG 用于转换多媒体文件的 命令行工具 格式之间&#xff08; ffmpeg\bin\ffmpeg.exe &#xff09; ffplay 基于 SDL 和 FFmpeg 库的简单媒体播放器 &#xff08; ffmpeg\bin\ffplay.exe &#xff0…

Java 函数式编程

一、简介 1.1 函数式编程的引进 在 Java 8 之前&#xff0c;Java 是没有很明确的函数式编程这么一说的&#xff0c;那之前的 Java 代码都是类、方法等组成的&#xff0c;若想要实现一个很简单的功能往往要写上很多代码&#xff0c;这就非常地不方便。于是&#xff0c;在 Java…