色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一文詳解什么是樹狀數組

算法與數據結構 ? 來源:程序員小灰    ? 作者:程序員小灰 ? 2021-06-11 10:03 ? 次閱讀

Part 1 我學它干啥?

樹狀數組,Binary Indexed Tree(簡稱BIT),是由Peter M. Fenwick在1994年發明的名字十分高大上,那么它是干什么的呢?

求和

求和是樹狀數組中的一個應用,并不是只能求和,本文使用求和作為例子。

現在有一個數組a,我們需要求很多次數組中不同區間的和,而且多次對a中隨意一項進行更改。

比如說a = {0, 1, 5, 3, 2, 4}

第一次求[1, 3],得到1 + 5 + 3 = 9

第二次求[2, 4],得到5 + 3 + 2 = 10

第三次,這時候我把a[2] += 2

第四次求[1, 5],得到1 + 7 + 3 + 2 + 4 = 17

[l, r]表示從下標l開始,到r結束的區間,包含l和r。

l: left

r: right

這時候很多同學想到的第一個方法,就是直接挨個加起來不就好了嗎?

可此題暗藏玄機,我們要進行多次求和啊,每一次都重新計算太慢,能不能提前加好一些區域,反復使用呢?

這就要請出我們的主角了——樹狀數組

Part 2 lowbit

樹狀數組的結構十分精妙,其中離不開一個基本運算——lowbit

pYYBAGDCyUmAI-2UAACcjSxNWmQ629.jpg

lowbit(i) 可以解釋為:i中最低位的1以及后面的0;或者你可以把它理解成i能被n整除,n還可以寫成2k

一種lowbit的實現方式為lowbit(x) = x & -x

long long lowbit(long long x) {

return x & -x;

}

還是拿172舉例子,化成二進制后我們發現除了尾部的100相同之外,其他位都不同,使用按位與能得到lowbit的值

poYBAGDCyVOAeJ9-AACEjV_ECQk145.jpg

Part 3 樹狀數組

既然名字叫樹狀數組,那它必然是個數組,可外表下藏著二叉樹的結構。

精巧的結構與lowbit密不可分,真是妙極了。

以下內容中,我們在這里管原始的數組叫做a,樹狀數組(經過處理)叫做bit,三個圖中的數字均為下標,不是值!

結構

pYYBAGDCyWGAU882AADclEz7wyc194.jpg

bit中存放了多個數的和,那么具體存了幾個,在哪里呢?

我們規定,bit[i]中存從右往左數lowbit(i)個數。

bit[i] = 在數組a中從 i - lowbit(i) + 1 到 i 求和

更改單個數值

首先,更改數據可以轉換成加法,我們這里討論加法,和更改是一樣的。

挨個加起來時,更改a[i]只需要動它一個就可以了。

可是在樹狀數組中,可能有好幾項,都包括這個a[i]。

拿a[3]來舉例子吧。

bit[3] 對應 a的[3, 3] 的和

bit[4] 對應 a的[1, 4] 的和

bit[8] 對應 a的[1, 8] 的和

bit[16] 對應 a的[1, 16] 的和

以上四個bit中的值都需要更改

pYYBAGDCyWiAd2hpAAEYesD_dPM603.jpg

在圖中,我們可以看出,4在3頭上,8在4頭上,16在8頭上。我們只需要找到一種方式,得到一個塊 頭上的塊,然后使用循環能推出整串。

如何找到自己頭上的數呢?

pYYBAGDCyieAc64XAAE4G2m5LLc951.jpg

圖中的6和橘色沒關系,是第二組例子

我們發現,在當前塊的位置加上當前塊的長度之后能跳到頭上。

我是這么理解的:加上一個當前塊后會把局部的空缺補上,合并成了一塊,而這塊也許也補了更大的空缺,這樣就一次跳了好幾級

上文定義規定了第i個塊長度 = lowbit(i),拿來用即可。

c++實現:

void add(int index, long long value) {

while (index 《= n) { // 更新直到最大的塊

node[index] += value; // 更新當前的塊

index += lowbit(index); // 加上一個自己的長度,補上空缺,得到下一個塊

}

}

區間求和

poYBAGDCyZeAYN7UAAD4XEu3eaw265.jpg

先考慮[1, r]的求和

從右往左取塊,將塊代表的數值加起來即可

圖中的例子:

第一次取到13,長度為lowbit(13) = 1

第二次13取完了從12開始取,長度為4,一次性將[9, 12]取完

第三次[9, 13]取完了從8開始,長度為8,取走[1, 8],到此[1, 13]全部取走c++實現

long long sum(int index) {

long long sum = 0;

while (index 》 0) {

sum += node[index];

index -= lowbit(index);

}

return sum;

}

那如果求和左端點不在1處呢?

對[l, r]求和,可以寫成sum(r) - sum(l - 1)

先把大區域[1, r]求出來,然后扣掉[1, l - 1]的部分,不就是[l, r]嗎?

構造

以上的“幻想”只是存在于樹已經有了之后,如何根據數組a(原始數組),來構造一棵樹呢?

一個簡單的方法:

把數組bit全初始化為0

遍歷整個數組a

對于每一個數組a[i],都對bit進行add(i, a[i])每一次add之后都能保證樹狀數組是正確的,全加一遍后自然構建出一整棵樹。

時間復雜度對比

下面的暴力指的是開頭提到的挨個相加。

求和

暴力:O(n)(挨個相加,加n次)

樹狀數組:O(log n)(結構與二叉樹相仿)更改

暴力:O(1)(改一次即可)

樹狀數組:O(log n)(需要改一串,但結構與二叉樹相仿)構造

暴力:O(n)(當做是讀入的復雜度)

樹狀數組:O(n log n)(做n次加法,每次加法為log n)樹狀數組適合在:多次求和,多次修改,數據量大的場景下使用。

如果無需支持修改,建議使用前綴和,構造O(n),求和O(1)

代碼

下面給出的是C++代碼。

BITMain為樹狀數組的使用案例,對應洛谷 樹狀數組https://www.luogu.com.cn/problem/P3374。

//

// Created by Cat-shao on 2021/2/9.

//

#include 《cstdio》

#include 《cstring》

using namespace std;

const long long MAX_N = 5000100;

long long lowbit(long long x) {

return x & -x;

}

class BIT {

public

long long node[MAX_N], n;

BIT(int _n) {

memset(node, 0, sizeof(node));

n = _n;

}

long long sum(int index) {

long long sum = 0;

while (index 》 0) {

sum += node[index];

index -= lowbit(index);

}

return sum;

}

void add(int index, long long value) {

while (index 《= n) {

node[index] += value;

index += lowbit(index);

}

}

};

int BITMain()

{

// https://www.luogu.com.cn/problem/P3374

int n, m, op, x, y;

long long value;

scanf(“%d%d”, &n, &m);

BIT tree = BIT(n);

for (int i = 1; i 《= n; ++i) {

scanf(“%lld”, &value);

tree.add(i, value);

}

for (int i = 0; i 《 m; ++i) {

scanf(“%d%d%d”, &op, &x, &y);

if (op == 1) {

tree.add(x, y);

} else if (op == 2) {

printf(“%lld

”, (tree.sum(y) - tree.sum(x - 1)));

}

}

return 0;

}

int main()

{

BITMain();

}

文章來源: 程序員小灰

圖片來源:編程的最初夢想
責任編輯:lq6

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • bit
    bit
    +關注

    關注

    0

    文章

    48

    瀏覽量

    32012

原文標題:什么是樹狀數組?讓這個12歲年輕人為你講解

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    數組與指針詳解

    數組與指針詳解分享,請多指教!
    發表于 12-15 11:21

    C語言數組詳解

    上述的語句把數組中第五個元素的值賦為 50.0。所有的數組都是以 0 作為它們第個元素的索引,也被稱為基索引,數組的最后個索引是
    的頭像 發表于 09-25 15:43 ?1.5w次閱讀
    C語言<b class='flag-5'>數組</b><b class='flag-5'>詳解</b>

    詳解藍牙模塊原理與結構

    電子發燒友網站提供《詳解藍牙模塊原理與結構.pdf》資料免費下載
    發表于 11-26 16:40 ?94次下載

    詳解精密封裝技術

    詳解精密封裝技術
    的頭像 發表于 12-30 15:41 ?1654次閱讀

    詳解分立元件門電路

    詳解分立元件門電路
    的頭像 發表于 03-27 17:44 ?3161次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文</b><b class='flag-5'>詳解</b>分立元件門電路

    詳解pcb和smt的區別

    詳解pcb和smt的區別
    的頭像 發表于 10-08 09:31 ?3341次閱讀

    詳解pcb地孔的作用

    詳解pcb地孔的作用
    的頭像 發表于 10-30 16:02 ?1637次閱讀

    詳解TVS二極管

    詳解TVS二極管
    的頭像 發表于 11-29 15:10 ?1580次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文</b><b class='flag-5'>詳解</b>TVS二極管

    詳解pcb不良分析

    詳解pcb不良分析
    的頭像 發表于 11-29 17:12 ?1158次閱讀

    詳解PCB半成品類型

    詳解PCB半成品類型
    的頭像 發表于 12-11 15:41 ?1357次閱讀

    詳解pcb的msl等級

    詳解pcb的msl等級
    的頭像 發表于 12-13 16:52 ?9556次閱讀

    詳解pcb微帶線設計

    詳解pcb微帶線設計
    的頭像 發表于 12-14 10:38 ?3142次閱讀

    詳解pcb的組成和作用

    詳解pcb的組成和作用
    的頭像 發表于 12-18 10:48 ?1528次閱讀

    詳解pcb回流焊溫度選擇與調整

    詳解pcb回流焊溫度選擇與調整
    的頭像 發表于 12-29 10:20 ?1642次閱讀

    異形創意LED顯示屏定制之智慧樹狀LED喇叭屏助力旅新征程

    智慧樹狀LED喇叭屏融合科技與藝術,成文旅新星,提供沉浸式視聽盛宴,可智能互動,推動旅產業升級,注入新活力與靈感。
    的頭像 發表于 11-14 16:00 ?161次閱讀
    異形創意LED顯示屏定制之智慧<b class='flag-5'>樹狀</b>LED喇叭屏助力<b class='flag-5'>文</b>旅新征程
    主站蜘蛛池模板: 国产精品成人在线播放| 国产亚洲精品在浅麻豆| 国产综合欧美区在线| 久亚洲AV无码专区A片| 日本人六九视频| 亚洲综合春色另类久久| 芭乐草莓樱桃丝瓜18岁大全| 国产亚洲精品久久久久久线投注 | 野花高清影视免费观看| 99视频在线国产| 国产网站免费观看| 女人高潮了拔出来了她什么感觉| 小便japanesewctv| 97影院理论午夜伦不卡偷| 国产色婷亚洲99精品AV在| 美女视频黄a视频全免费网站色窝| 微拍秒拍99福利精品小视频| 999久久久无码国产精蜜柚| 国产亚洲精品久久久久久国| 欧美亚洲日韩一道免费观看| 亚洲性夜夜夜色综合网| 动漫美女人物被黄漫在线看| 巨胸美乳中文在线观看| 亚洲AV无码影院在线播放| jj插入bb| 久久婷婷五月综合色情| 午夜影院费试看黄| 被窝国产理论一二三影院 | 免费看男人J放进女人J无遮掩| 亚洲 欧美 日韩 国产 视频| 99热在线精品免费全部my| 九九热久久只有精品2| 熟妇少妇任你躁在线无码| 97亚洲狠狠色综合久久位| 久久激情网| 亚洲AV 日韩 国产 有码| 超碰97免费人妻| 欧美日本高清动作片www网站| 又亲又揉摸下面视频免费看| 国产三级在线观看免费| 肉色欧美久久久久久久蜜桃|