当前位置: 首页 > wzjs >正文

外包网站会自己做原型吗做图片网站会被

外包网站会自己做原型吗,做图片网站会被,网站开发中数据库的设计原则,没有做等保的网站不能上线对吗树状数组是算法中一种十分重要的数据结构!通过这篇文章你能够快速的get到树状数组的精髓,即使是第一次接触树状数组也能让你完全弄懂 目录 管辖区间 怎么让计算机计算 lowbit? 区间初始化: 更新区间 计算前缀和: 计算任意区…

树状数组是算法中一种十分重要的数据结构!通过这篇文章你能够快速的get到树状数组的精髓,即使是第一次接触树状数组也能让你完全弄懂

目录

管辖区间

怎么让计算机计算 lowbit?

区间初始化:

更新区间

计算前缀和:

计算任意区间和:


先来举个例子:我们想知道  a[1...7]的前缀和,怎么做?

一种做法是:a[1]  +a[2] + a[3] + a[4] .... a[7],需要求 7个数的和。

但是如果已知三个数 A,B,C,,A = a[1...4] 的总和,B = [5...6] 的总和和C = a[7..7](其实就是a[7] 自己)。你会怎么算?你一定会回答:A + B + C,只需要求  3个数的和。

这就是树状数组能快速求解信息的原因:我们总能将一段前缀 [1..n] 拆成 不多于 \log n 段区间,使得这 \log n 段区间的信息是 已知的

于是,我们只需合并这  \log n  段区间的信息,就可以得到答案。相比于原来直接合并  个信息,效率有了很大的提高。不难发现信息必须满足结合律,否则就不能像上面这样合并了。

那么如何划分a[1.. n]呢? 咱们直接先说结论吧  (图片出自灵神)

管辖区间

那么问题来了,c[x](x \ge 1) 管辖的区间到底往左延伸多少?也就是说,区间长度是多少?

树状数组中,规定 c[x] 管辖的区间长度为 2^{k},其中:

  1. 设二进制最低位为第 0 位,则 k 恰好为 x 二进制表示中,最低位的 1 所在的二进制位数;
  2. 2^k(c[x] 的管辖区间长度)恰好为 x 二进制表示中,最低位的 1 以及后面所有 0 组成的数。举个例子,c_{88} 管辖的是哪个区间?

因为 88_{(10)}=01011000_{(2)},其二进制最低位的 1 以及后面的 0 组成的二进制是 1000,即 8,所以c_{88}管辖 8 个 a 数组中的元素。

因此,c_{88}代表 a[81 \ldots 88]的区间信息。

我们记 x 二进制最低位 1 以及后面的 0 组成的数为 \operatorname{lowbit}(x),那么 c[x] 管辖的区间就是 [x-\operatorname{lowbit}(x)+1, x]。 为什么要加1呢这个理解的十分简单你看c_{88}

这里注意:\boldsymbol{\operatorname{lowbit}}指的不是最低位 1 所在的位数 \boldsymbol{k},而是这个 1 和后面所有 0 组成的 \boldsymbol{2^k}

怎么让计算机计算 lowbit?

(如果是人那么一看就知道了,那么如何让计算机理解呢?)

根据位运算知识,可以得到 lowbit(x) = x & -x。这是一种简单的实现方法

如果对位运算不是十分敏感的可能不知道为什么是这样算的,我们可以假设x是 7那么相应的lowbit(7) 为1 对于负数的二进制就是求法:

  1.         先求绝对值的二进制。对于-7来说7的二进制是111
  2.         再求第一步的补码那么就是000
  3.         在将第二步得到的值 加一得到 001,那么001就是-7的二进制,当然前面缺位补0

那么言归正传 7 & -7 就是111 & 001 那么lowbit就是001 十进制就是1表示当前lowbit(7)值为1,并且区间只有一个值

def lowbit(self, x):return x & -x

补充:对于计算机是这样理解的,那么对于我们还有一种更容易的理解方式,参考灵神题解

区间初始化:

    def __init__(self, nums: List[int]):n = len(nums)tree = [0] * (n + 1)for i, x in enumerate(nums, 1):tree[i] += x nxt = i + (i & -i) #下一个关键区间的右端点,这也就说明当前区间在下一个区间内,那么就要操#这里的 i & -i 就是lowbitif nxt <= n:tree[nxt] += tree[i] self.nums = nums self.tree = tree 

更新区间

假设下标 x 发生了更新,那么所有包含 x 的关键区间都会被更新。

例如下标 5 更新了,那么关键区间 [5,5],[5,6],[1,8],[1,16] 都需要更新,这三个关键区间的右端点依次为 5,6,8,16。

如果在 5-6,6-8,8-16 之间连边(其它位置也同理),我们可以得到一个什么样的结构?

如下图,这些关键区间可以形成如下树形结构(区间元素和保存在区间右端点处)。


 

注意到:

5+lowbit(5)=5+1=6

6+lowbit(6)=6+2=8

8+lowbit(8)=8+8=16

猜想:如果 x 是一个被更新的关键区间的右端点,那么下一个被更新的关键区间的右端点为 x+lowbit(x)。

我们需要证明两点:

  1. 右端点为 x 的关键区间,被右端点为 x+lowbit(x) 的关键区间包含。
  2. 右端点在 [x+1,x+lowbit(x)−1] 内的关键区间,与右端点为 x 的关键区间没有任何交集。

1) 的证明

2 )的证明

以上两点成立,就可以保证 x+lowbit(x) 是「下一个」被更新的关键区间的右端点了。

由于任意相邻被更新的关键区间之间,没有其余关键区间包含 x,所以我们可以找到所有包含 x 的关键区间,具体做法如下。

def update(self, index: int, val: int) -> None:#将nums[index]更新为valdelta = val - self.nums[index] #val是目标值,相当于把当前值增加了deltaself.nums[index] = val #把当前值更新了i = index + 1 #为什么index要加1呢,因为index是下标0 --n-1 为了和1--n的c的下标对应肯定加1while i < len(self.tree):self.tree[i] += delta i += i & -i #手搓lowbit 

计算前缀和:

在树状数组中计算1-n的前缀和有更快的方法那就是访问树状数组的结构

def prefixsum(self, i: int) -> int: #计算前缀和是为了计算区间,每一个区间都可以用前缀和表示s = 0while i:s += self.tree[i]i  = i - (i & -i) #相当于i - lowbit(),其实就是前缀和跳到上一个关键区间的右端点了#相较于传统计算前缀和更快,这里的prefixsum是计算1-i的前缀和

计算任意区间和:

因为本质上所有子区间都可以写成两个区间和的差

def sumRange(self, left: int, right: int) -> int:return self.prefixsum(right + 1) - self.prefixsum(left)

关于相关题目,博主会尽快整理发表。

下面是全部实现代码和解释:

class NumArray:__slots__ = 'nums', 'tree'#__slots__是一个特殊的内置类属性,它可以用于定义类的属性名称的集合。一旦在类中定义了__slots__属#性,Python将限制该类的实例只能拥有__slots__中定义的属性。这有助于减少每个实例的内存消耗,#提高属性访问速度,同时也可以防止意外添加新属性。#最右端为i的长为lowbit(i)的关键区间是 [i - lowbit(i) + 1 , i]def __init__(self, nums: List[int]):n = len(nums)tree = [0] * (n + 1)for i, x in enumerate(nums, 1):tree[i] += x nxt = i + (i & -i) #下一个关键区间的右端点,这也就说明当前区间在下一个区间内,那么就要操#这里的 i & -i 就是lowbitif nxt <= n:tree[nxt] += tree[i] self.nums = nums self.tree = tree def update(self, index: int, val: int) -> None:#将nums[index]更新为valdelta = val - self.nums[index] #val是目标值,相当于把当前值增加了deltaself.nums[index] = val #把当前值更新了i = index + 1 #为什么index要加1呢,因为index是下标0 --n-1 为了和1--n的c的下标对应肯定加1while i < len(self.tree):self.tree[i] += delta i += i & -i #手搓lowbit # #需要证明两点:# 1.右端点为x的关键区间,被右端点为x + lowbit(x)的关键区间包含# 2.右端点为[x + 1, x + lowbit(x) - 1]内的关键区间,与右端点为x的关键区间没有任何交集def prefixsum(self, i: int) -> int: #计算前缀和是为了计算区间,每一个区间都可以用前缀和表示s = 0while i:s += self.tree[i]i  = i - (i & -i) #相当于i - lowbit(),其实就是前缀和跳到上一个关键区间的右端点了#相较于传统计算前缀和更快,这里的prefixsum是计算1-i的前缀和return s def sumRange(self, left: int, right: int) -> int:return self.prefixsum(right + 1) - self.prefixsum(left)

本博客参考灵神题解和树状数组

希望这篇文章能帮到你,感谢点赞收藏!


文章转载自:

http://1B8MXICJ.jtdzn.cn
http://EovdSA6a.jtdzn.cn
http://yb8ojilW.jtdzn.cn
http://10md1Hn1.jtdzn.cn
http://PeeGGsOg.jtdzn.cn
http://hh2gjOKq.jtdzn.cn
http://TDOo5S6I.jtdzn.cn
http://QW4AaPJA.jtdzn.cn
http://l64JMmwO.jtdzn.cn
http://d4vGQyMD.jtdzn.cn
http://Di0mgdbn.jtdzn.cn
http://p3gOa6mx.jtdzn.cn
http://teaO1e29.jtdzn.cn
http://AtcHZv9H.jtdzn.cn
http://cu71P8tK.jtdzn.cn
http://IA7hMFO8.jtdzn.cn
http://wjHph09C.jtdzn.cn
http://pngNeyuX.jtdzn.cn
http://vsf04srS.jtdzn.cn
http://lWI8qhh7.jtdzn.cn
http://sSHSM0A7.jtdzn.cn
http://BkUUxkIN.jtdzn.cn
http://kdNqNpku.jtdzn.cn
http://UAh3sARH.jtdzn.cn
http://ZQ7xlt5V.jtdzn.cn
http://0Azhk5Oj.jtdzn.cn
http://wOCEB3Yl.jtdzn.cn
http://A4xyA1Nd.jtdzn.cn
http://odyTnzK7.jtdzn.cn
http://fBSnIGe5.jtdzn.cn
http://www.dtcms.com/wzjs/640011.html

相关文章:

  • 番禺区网站建设龙岩市网站建设
  • wordpress重写插件优化设计五年级上册语文答案
  • 在线建设房屋设计网站.net美食网站开发源代码
  • 湖南企业网站营销设计免费域名网站的
  • 做家政公司网站孟州网站建设
  • 影视自助建站建筑设计前景怎么样
  • 高端网站建设品牌wordpress页面菜单
  • 怎么免费创建自己的网站平台和创互联的网站是多少
  • 网站图片等比缩小网页布局设计的一般步骤
  • 山东济宁省建设厅官方网站教育培训机构十大排名
  • 网站需要的栏目和内容廊坊网站建站网站
  • 网站建设策划书选题游戏加盟
  • 电子图书网站开发的目的钉钉小程序开发工具
  • 怎么做自己的html网站简单的响应式网页实例
  • 滨海新区做网站电商详情页素材
  • 提升网站访问量网站制作是什么公司
  • 网站 建设 申请公司网络维修
  • 网站标签怎么做跳转餐饮系统网站建设
  • 福州招聘网站有哪几个360网站弹窗推广怎么做的
  • 青岛市崂山区建设局网站手机无法安装wordpress
  • 做网站和程序员哪个好点外包公司是怎么回事
  • 会泽做网站wordpress怎么增加语言包
  • 做网站生成二维码王串场街网站建设公司
  • 商务网站建设与维护 课件有哪些做共享充电宝的网站
  • 微信公众号做公司网站wordpress是什么标准
  • 可以做网站的行业广州哪里能做英文版核酸
  • 网站外链常见的搜索引擎有哪些
  • 成都水高新区建设局官方网站抖音代运营需要什么
  • 公司网站的开发和网版的重要性wordpress更改ip
  • php网站开发步骤福步外贸论坛下载