日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

l2-004 这是二叉搜索树吗? (25分)_什么是 “线段树” ?

發布時間:2025/4/5 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 l2-004 这是二叉搜索树吗? (25分)_什么是 “线段树” ? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線段樹是一個復雜的數據結構,比較難理解,也比較難解釋清楚。在我將這個數據結構反復學習了五遍的時候,我終于有了信心寫出這篇介紹線段樹的文章。希望大家能夠掌握這種數據結構。

這篇文章比較長,建議大家耐心閱讀,好好消化吸收哦~~

前置內容

學習線段樹前,你需要掌握二叉搜索樹,不太了解的小伙伴,可以看看小灰之前發布的紅黑樹漫畫,前半部分講解了二叉搜索樹:

漫畫:什么是紅黑樹?

我只補充一個內容,就是關于二叉搜索樹如何編號。

二叉搜索樹的根節點編號為1,對于每個節點,假如其編號為N,它的左兒子編號為2N,右兒子編號為2N+1。因此,整個二叉搜索樹的編號如下:

上圖當中,結點上方的數字是結點的編號,后續為了簡單,把編號寫在結點內不。

有讀者可能要問了,為什么3的兒子是6和7,而不是4和5呢?這是因為雖然節點4和節點5不存在,但是仍然應該為他們保留4和5這2個編號,你可以把這棵樹看成這樣:

線段樹的概念

線段樹,英文名稱是Segment Tree,其本質也是一個二叉搜索樹,區別在于線段樹的每一個節點記錄的都是一個區間,每個區間都被平均分為2個子區間,作為它的左右兒子。比如說區間[1,10],被分為區間[1,5]作為左兒子,區間[6,10]作為右兒子:

為什么要設計這樣奇怪的數據結構呢?

線段樹主要適用于某些相對罕見的應用場景:

比如給定了若干元素,要求統計出不同區間范圍內,元素的個數。

現在我們已經知道了什么是線段樹,那么看一個利用線段樹的例子。

線段樹的存儲與建造

這是一個序列:

現在我們要用它完成一個區間求和的任務。

區間求和就是指求序列中一段區間的所有元素之和。比如說上面的序列,區間[1,5]的和為元素1+元素2+元素3+元素4+元素5,也就是14。再舉一個例子,區間[9,10]的和為9。

在學習線段樹的概念的時候,我們就知道線段樹的每個節點都存儲了一個區間。比如說對于[1,10]這個節點,也就是這棵線段樹的根節點,那么它的值為1+5+1+3+4+2+0+9+0+9=34??次覀儼堰@棵樹填完:

(當一個區間的左右邊界已經相等時,比如[1,1],表示這個區間內只有一個元素了,此時不能再分割,因此它就沒有左右兒子節點了)

現在就讓我們用代碼實現線段樹:

【代碼片段 1】?用一個類Node表示線段樹的節點:

class?Node?{
?????int?l;?//?l是區間左邊界
?????int?r;?//?r是區間右邊界
?????int?sum;?//?sum是區間元素和

?????public?Node?(int?l,?int?r,?int?sum){
?????????this.l?=?l;
?????????this.r?=?r;
?????????this.sum?=?sum;
?????}
}

【代碼解析 1】?線段樹的任意節點都有3個屬性:

  • 區間的左邊界l
  • 區間的右邊界r
  • 區間的元素和sum

比如說在上面的線段樹中,區間[1,10]這個元素:

  • 左邊界為1
  • 右邊界為10
  • 元素和為34

【代碼片段 2】?定義元素個數、原序列和線段樹

static?int?n?=?10;?//?n是元素個數
static?int[]?array?=?{0,?1,?5,?1,?3,?4,?2,?0,?9,?0,?9};?
//?array是原序列(第一個0是占array[0]位的)
static?Node[]?tree?=?new?Node[4*n];

static?void?initTree?(){
????for(int?i?=?0;?i?????????tree[i]?=?new?Node(0,?0,?0,?0);
????}
}

【代碼解析 2】?首先我們在上文已經定義了元素個數和原序列。他們的值如下:

  • 元素個數為10個
  • 原序列為[0,1,5,1,3,4,2,0,9,0,9]

現在問題在于,存儲線段樹的數組應該開多大的空間?根據證明發現,一個有n個元素的序列,所對應的線段樹至少需要大小為4n的數組來存儲。這一類證明網上有很多,讀者可以自行查閱一下。

我們用inittree這個函數進行線段樹初始化(tree數組初始值為null,不初始化會報錯,我在這個地方卡了好久)

【代碼片段 3】?updateNode函數負責更新節點的值:

static void?updateNode?(int?num)?{?//?num是當前節點序號
????tree[num].sum?=?tree[num?*?2].sum?+?tree[num?*?2?+?1].sum;
}

【代碼解析 3】?仔細觀察前面的線段樹可以發現,每一個節點的值都等于其左右兒子值的和。我們剛剛學會,一個編號為n的節點,其左右兒子分別為2n和2n+1。因此我們把num的值更新為2num+2num+1,也就是其左右兒子的和。

【代碼片段 4】?build函數建造線段樹:

static void?build?(int?l,?int?r,?int?num)?{?//?建樹
????tree[num].l?=?l;
????tree[num].r?=?r;
????if?(l?==?r)?{?//?l?=?r說明到達葉子節點
????????tree[num].sum?=?array[l];
????????return;
????}
????int?mid?=?(l?+?r)?/?2;
????build(l,?mid,?num?*?2);?//?遞歸左兒子
????build(mid + 1,?r,?num?*?2?+?1);?//?遞歸右兒子
????updateNode(num);
}

【代碼解析 4】?函數從區間[l,r]開始遞歸遍歷整棵線段樹,每一次都遞歸它的左右兒子,到葉子節點時結束。遞歸每一個兒子時,都對它進行更新。這樣下來就完成了整棵樹的初始化。

線段樹的單點修改

現在假如我們需要把第6個元素從2修改為3:

那么就會有很多的區間相應的改變。比如說區間[5,7],從4+2+0=6變成了4+3+0=7?,F在讓我們手動模擬一下線段樹的單點修改過程。這里假設我們需要把元素6從2變成3:

首先,從根節點開始遍歷,發現含有元素6的區間是根節點的右兒子,與左兒子沒有關系。因此將修改目標鎖定到右兒子:

第二步,發現含有6的區間是左兒子,因此把目標放到左兒子上:

第三步同理:

第四步同理:

此時發現這是一個葉子節點,因此對它進行更新,從2變成3:

返回到上一層:

接下去同理:

然后我們跳過演示,讀者可以自己試試看用同樣的方法修改這棵樹。最后修改完應該是這樣的:

根節點最后應該從34變成35,我經常會忘記修改它的值,大家千萬不要忘記修改它。

演示完以后我們分析一下時間復雜度。如果我們使用線段樹修改元素,每次都是折半操作,相當于二分查找的速度,時間復雜度僅僅是對數級別,也就是?。

【代碼片段 5】?modify函數實現單點修改:

static void?modify?(int?i,?int?value,?int?num)?{?//?把元素i修改為值value
????if?(tree[num].l?==?tree[num].r)?{?//?到達葉子節點
????????tree[num].sum?=?value;
????????return;
????}
????int?mid?=?(tree[num].l?+?tree[num].r)?/?2;
????if?(i?<=?mid)?{
????????modify(i,?value,?num?*?2);?//?遞歸左兒子
????}
????else?{
????????modify(i,?value,?num?*?2?+?1);?//?遞歸右兒子
????}
????updateNode(num);
}

【代碼解析 5】?這一段代碼也不是很難。每一次我們都從根開始遞歸遍歷。我們先判斷要更改的元素屬于當前節點的左兒子還是右兒子,并且遞歸到該節點。遞歸結束后更新當前節點的值。假如遍歷到葉子節點,說明我們已經遍歷到了想要修改的元素,那么我們直接把該節點的值修改為value就可以了。

到這里我們已經學會了單點修改的方法了。接下來讓我們更進一步,學習區間修改。

線段樹的區間修改

首先讓我們明確一下區間修改的概念:

單點修改,大致是以下兩個步驟:

  • 找到需要修改的點
  • 修改這個點
  • 而區間修改是這樣兩個步驟:

  • 找到需要修改的區間
  • 修改這段區間內的所有點
  • 好的,概念我們明白了,現在要知道如何實現這個功能。首先我們看一看區間修改可能的情況:

  • 需要修改的區間包含在兒子之內:

    為大家畫個圖:

    我們看到需修改區間[6,8]包含在未修改區間的右兒子里。這種情況很簡單,我們直接遞歸到右兒子即可。

  • 需要修改的區間被拆開:

    還是畫一個圖:

    這時4屬于左兒子,但是5和6屬于右兒子。這怎么辦呢?最直接的方法是把這個區間拆成兩半,屬于左兒子的放一邊,屬于右兒子的放一邊,像這樣:

  • 兩種情況分類討論后,我們就要考慮如何修改區間了。

    最簡單的方法就是把這些區間挨個兒修改。但是大家可以試試看,這種方法比暴力還要慢好幾倍。因此我們需要使用懶惰標記

    現在假如我們需要把區間[5,7]每個元素增加2:

    首先,5屬于根節點的左兒子,而6和7屬于根節點的右兒子,因此兩邊都要進行修改。我們可以先修改左兒子:

    5屬于當前節點的右兒子,因此我們鎖定右兒子:

    5屬于當前節點的右兒子,那么我們修改右兒子。我們發現右兒子就是5。當前只有一個元素,因此我們把當前的值+2,并為其打上一個懶惰標記,懶惰標記的值也是2:

    之后向上回溯,每一個節點都進行更新,也就是說每一個節點都更新為其左兒子+右兒子,最后更新完是這樣的:

    到目前為止,懶惰標記還沒有發揮作用,但是我們可以看一看6和7這段區間的修改。首先因為6和7在根節點的右兒子,因此我們先遍歷右兒子:

    接著因為6和7在當前節點的左兒子,因此我們遍歷左兒子:

    之后我們發現6和7就是當前節點的左兒子,因此我們直接遍歷到左兒子,修改其值并打上懶惰標記。需要指出的是,因為6~7有2個元素,因此增加的值要乘2,也就是從+2變為+4,但懶惰標記的值不用乘2:

    此時讓我們思考一個問題:

    我們還需要遍歷修改[6,6]和[7,7]嗎?

    這時就不用了,因為我們已經打上了懶惰標記,懶惰標記的初衷就是延遲修改,因此我們當然不需要再修改這兩個節點了?,F在讓我們一鼓作氣,回溯到根節點,完成所有更新:

    現在我們一起用代碼實現:

    【代碼片段 6】?為Node類添加懶惰標記:

    class?Node?{
    ?????int?l;?//?l是區間左邊界
    ?????int?r;?//?r是區間右邊界
    ?????int?sum;?//?sum是區間元素和
    ?????int?lazy;?//?lazy是懶惰標記

    ?????public?Node?(int?l,?int?r,?int?sum,?int?lazy){
    ?????????this.l?=?l;
    ?????????this.r?=?r;
    ?????????this.sum?=?sum;
    ?????????this.lazy?=?lazy;
    ?????}
    }

    【代碼解析 6】?新增了lazy變量作為懶惰標記。

    【代碼片段 7】?modifySegment函數實現區間修改的代碼:

    static void?modifySegment(int?l,?int?r,?int?value,?int?num)?{?//?[l,r]每一項都增加value
    ????if?(tree[num].l?==?l?&&?tree[num].r?==?r)?{?//?找到當前區間
    ????????tree[num].sum?+=?(?r?-?l?+?1?)?*?value;?//?r-l+1是區間元素個數
    ????????tree[num].lazy?+=?value;
    ????????return;
    ????}
    ????int?mid?=?(tree[num].l?+?tree[num].r)?/?2;
    ????if?(r?<=?mid)?{?//?在左區間
    ????????modifySegment(l,?r,?value,?num?*?2);
    ????}
    ????else?if?(l?>?mid)?{?//?在右區間
    ????????modifySegment(l,?r,?value,?num?*?2?+?1);
    ????}
    ????else?{?//?分成2塊
    ????????modifySegment(l,?mid,?value,?num?*?2);
    ????????modifySegment(mid?+?1,?r,?value,?num?*?2?+?1);
    ????}
    ????updateNode(num);
    }

    【代碼解析 7】??首先,按照開始講的3種情況,進行分類討論(情況分別是:完全在左區間,完全在右區間,分成了2塊),并且向下遞歸。

    線段樹的區間查詢

    區間查詢,顧名思義就是查詢一段區間內的元素和。那么如何實現呢?

    不急,現在我們來看這樣一種情況:

    [1,2]有一個懶惰標記2?,F在假如我要求[1,1]的值怎么辦?

    涼拌

    為什么我這么說?因為[1,2]這個節點有一個懶惰標記,但是[1,1]卻沒有被更新,這是一個問題。

    此時我們就要實現一個函數,用于把懶惰標記下傳給兒子們,稱為pushdown函數。下面直接給代碼,解析部分請看代碼解析吧:

    【代碼片段 8】?使用pushdown函數下傳懶惰標記:

    static void?pushdown?(int?num)?{
    ????if(tree[num].l?==?tree[num].r)?{?//?葉節點不用下傳標記
    ????????tree[num].lazy?=?0;?//?清空當前標記
    ????????return;
    ????}
    ????tree[num?*?2].lazy?+=?tree[num].lazy;?//?下傳左兒子的懶惰標記
    ????tree[num?*?2?+?1].lazy?+=?tree[num].lazy;?//?下傳右兒子的懶惰標記
    ????tree[num?*?2].sum?+=?(tree[num?*?2].r?-?tree[num?*?2].l?+?1)?*?tree[num].lazy;?//?更新左兒子的值
    ????tree[num?*?2?+?1].sum?+=?(tree[num?*?2?+?1].r?-?tree[num?*?2?+?1].l?+?1)?*?tree[num].lazy;?//?更新右兒子的值
    ????tree[num].lazy=0;?//?清空當前節點的懶惰標記
    }

    【代碼解析 8】?下傳懶惰標記步驟有3步:

  • 將懶惰標記傳遞給兒子
  • 更新兒子的值
  • 清空當前節點的懶惰標記
  • 需要注意的是,葉子節點不用下傳標記。

    現在我們完成了pushdown函數的編寫,可以開始學習區間查詢了。剛才我們完成了區間修改,并且將原序列修改為了[1,5,1,3,6,4,2,9,0,9]?,F在我們接著實現區間查詢問題。假如我們要查詢區間[5,6]:

    正如我們所見,答案為10?,F在告訴大家一個好消息,那就是區間查詢的大致步驟其實和區間修改沒有什么出入。讓我們來實踐一下:

    首先,5和6分別屬于根節點的左兒子和右兒子,那我們先遍歷左兒子:

    接著繼續往下:

    往下查找到[5,5]:

    記錄好這邊答案為6。接著我們看根節點的右兒子,查找元素6:

    向下搜索到[6,8]:

    搜索到[6,7]:

    此時我們需要下傳[6,7]的懶惰標記,并且更新[6,6]的值,如下:

    最后遍歷到[6,6],值為4,與剛才得到的6相加,答案就是10:

    那么我們上代碼:

    【代碼片段 9】?query函數實現區間查詢:

    static int?query?(int?l,?int?r,?int?num)?{
    ????if?(tree[num].lazy?!=?0)?{?//?下傳懶惰標記
    ????????pushdown(num);
    ????}
    ????if?(tree[num].l?==?l?&&?tree[num].r?==?r)?{?//?找到當前區間
    ????????return?tree[num].sum;
    ????}
    ????int?mid?=?(tree[num].l?+?tree[num].r)?/?2;
    ????if?(r?<=?mid)?{?//?在左區間
    ????????return?query(l,?r,?num?*?2);
    ????}
    ????if?(l?>?mid)?{?//?在右區間
    ????????return?query(l,?r,?num?*?2?+?1);
    ????}
    ????return?query(l,?mid,?num?*?2)?+?query(mid?+?1,?r,?num?*?2?+?1);?//?分成2塊
    }

    【代碼解析 9】?步驟與區間修改完全相同,記得要pushdown一下就行。

    思考與探究

    下面讓我們進行一些對于線段樹的思考與探究:

    【思考 1】?線段樹都應用于什么環境?除了區間和外,能否解決更多問題?比起別的樹有什么優勢?

    【答案 1】?線段樹一般多用于區間問題。在本文中我們解決的是區間和,但是也能解決更多的問題,比如區間平方和等等。線段樹只能解決符合下面條件的問題:

    當區間[l,r]可以由[l,mid(l,r)]和[mid(l,r) + 1,r]得到答案

    我們舉幾個滿足條件的例子:

    • 區間[5,8]的區間和,可以由[5,6]的區間和加上[7,8]的區間和得到。
    • 區間[5,8]的最小值,等于區間[5,6]的最小值與[7,8]的最小值的最小值。

    但是還有一些不滿足條件:

    • 區間[5,8]的最長上升子序列。

    另外就是線段樹比起別的樹的特點。線段樹屬于二叉搜索樹,像我們熟悉的紅黑樹、AVL樹其實也都屬于二叉搜索樹。只不過不同的二叉搜索樹用處不相同。線段樹比起別的樹,它的最大特點就是用作存儲區間的特性。

    【思考 2】?線段樹和前綴和算法有什么優劣區別嗎?

    【答案 2】?寫到這里并不清楚各位是否明白前綴和算法。這里給大家簡單介紹一下:

    對于任何一個序列,都能制作一個相對應的前綴和數組。對于一個序列來講,假如我們用pre表示前綴和數組,那么pre[i]就表示區間[1,i]的區間和,比如pre[3]為array[1]+array[2]+array[3],也就是7。

    現在我們可用pre[i]表示區間[1,i],那么假如有一個任意區間[l,r],我們應該怎么表示它的區間和呢?仔細思考一下不難發現,區間[l,r]的區間和其實就是區間[1,r]減去區間[1,l - 1],剩下的也就是區間[l,r]了。因此我們可用pre[r]-pre[l-1]表示。

    舉個例子,區間[3,5]的和為1+3+4=8,相當于區間[1,5]減去區間[1,(3 - 1)],也就是14-6=8。

    我們發現,使用前綴和只要做一個減法就能得到區間和,而線段樹還要遍歷好多次,那是不是說,前綴和甚至要快于線段樹呢?我們可以來對比一下線段樹和前綴和的時間復雜度:

    算法名稱初始化修改查詢
    前綴和O(n)O(n)O(1)
    線段樹O(log n)O(log n)O(log n)

    我們發現,線段樹比起前綴和有更加穩定的特點。它的每一項都是對數級別。而前綴和雖然查詢非常快,但是修改速度就相對慢很多。因此我們認為,假如不需要進行元素的修改操作,那么我們一般選擇前綴和。如果需要進行元素修改操作,那么線段樹更為合適

    線段樹的完整代碼

    最后,附上線段樹的完整代碼實現:

    static?int?n?=?10;?//?n是元素個數
    static?int[]?array?=?{0,?1,?5,?1,?3,?4,?2,?0,?9,?0,?9};
    //?array是原序列(第一個0是占array[0]位的)
    static?Node[]?tree?=?new?Node[4*n];?//?tree是線段樹

    public?static?void?main(String[]?args)?{
    ????initTree();
    ????build(1,?10,?1);?//?利用build函數建樹
    ????System.out.println("操作1:[2,5]的區間和是:"?+?query(2,?5,?1));
    ????//?利用query函數搜索區間和
    ????modify(5,?9,?1);?//?利用modify函數實現單點修改(元素5從4改為9)
    ????System.out.println("操作2:元素5從4改為9,此時[2,5]的區間和是:"?+?query(2,?5,?1));
    ????modifySegment(3,?4,?3,?1);
    ????//?利用modifySegment函數將[3,4]每個元素增加3
    ????System.out.println("操作3:區間[3,4]每個元素+3,此時[2,5]的區間和是:"?+?query(2,?5,?1));
    }

    static?void?initTree?(){
    ????for(int?i?=?0;?i?????????tree[i]?=?new?Node(0,?0,?0,?0);
    ????}
    }

    static?void?updateNode?(int?num)?{?//?num是當前節點序號
    ????tree[num].sum?=?tree[num?*?2].sum?+?tree[num?*?2?+?1].sum;
    }

    static?void?build?(int?l,?int?r,?int?num)?{?//?建樹
    ????tree[num].l?=?l;
    ????tree[num].r?=?r;
    ????if?(l?==?r)?{?//?l?=?r說明到達葉子節點
    ????????tree[num].sum?=?array[l];
    ????????return;
    ????}
    ????int?mid?=?(l?+?r)?/?2;
    ????build(l,?mid,?num?*?2);?//?遞歸左兒子
    ????build(mid?+?1,?r,?num?*?2?+?1);?//?遞歸右兒子
    ????updateNode(num);
    }

    static?void?modify?(int?i,?int?value,?int?num)?{?//?把元素i修改為值value
    ????if?(tree[num].l?==?tree[num].r)?{?//?到達葉子節點
    ????????tree[num].sum?=?value;
    ????????return;
    ????}
    ????int?mid?=?(tree[num].l?+?tree[num].r)?/?2;
    ????if?(i?<=?mid)?{
    ????????modify(i,?value,?num?*?2);?//?遞歸左兒子
    ????}
    ????else?{
    ????????modify(i,?value,?num?*?2?+?1);?//?遞歸右兒子
    ????}
    ????updateNode(num);
    }

    static?void?modifySegment(int?l,?int?r,?int?value,?int?num)?{?//?[l,r]每一項都增加value
    ????if?(tree[num].l?==?l?&&?tree[num].r?==?r)?{?//?找到當前區間
    ????????tree[num].sum?+=?(?r?-?l?+?1?)?*?value;?//?r-l+1是區間元素個數
    ????????tree[num].lazy?+=?value;
    ????????return;
    ????}
    ????int?mid?=?(tree[num].l?+?tree[num].r)?/?2;
    ????if?(r?<=?mid)?{?//?在左區間
    ????????modifySegment(l,?r,?value,?num?*?2);
    ????}
    ????else?if?(l?>?mid)?{?//?在右區間
    ????????modifySegment(l,?r,?value,?num?*?2?+?1);
    ????}
    ????else?{?//?分成2塊
    ????????modifySegment(l,?mid,?value,?num?*?2);
    ????????modifySegment(mid?+?1,?r,?value,?num?*?2?+?1);
    ????}
    ????updateNode(num);
    }

    static?void?pushDown(int?num)?{
    ????if(tree[num].l?==?tree[num].r)?{?//?葉節點不用下傳標記
    ????????tree[num].lazy?=?0;?//?清空當前標記
    ????????return;
    ????}
    ????tree[num?*?2].lazy?+=?tree[num].lazy;?//?下傳左兒子的懶惰標記
    ????tree[num?*?2?+?1].lazy?+=?tree[num].lazy;?//?下傳右兒子的懶惰標記
    ????tree[num?*?2].sum?+=?(tree[num?*?2].r?-?tree[num?*?2].l?+?1)?*?tree[num].lazy;?//?更新左兒子的值
    ????tree[num?*?2?+?1].sum?+=?(tree[num?*?2?+?1].r?-?tree[num?*?2?+?1].l?+?1)?*?tree[num].lazy;?//?更新右兒子的值
    ????tree[num].lazy=0;?//?清空當前節點的懶惰標記
    }

    static?int?query?(int?l,?int?r,?int?num)?{
    ????if?(tree[num].lazy?!=?0)?{?//?下傳懶惰標記
    ????????pushDown(num);
    ????}
    ????if?(tree[num].l?==?l?&&?tree[num].r?==?r)?{?//?找到當前區間
    ????????return?tree[num].sum;
    ????}
    ????int?mid?=?(tree[num].l?+?tree[num].r)?/?2;
    ????if?(r?<=?mid)?{?//?在左區間
    ????????return?query(l,?r,?num?*?2);
    ????}
    ????if?(l?>?mid)?{?//?在右區間
    ????????return?query(l,?r,?num?*?2?+?1);
    ????}
    ????return?query(l,?mid,?num?*?2)?+?query(mid?+?1,?r,?num?*?2?+?1);?//?分成2塊
    }

    static?class?Node?{
    ????int?l;?//?l是區間左邊界
    ????int?r;?//?r是區間右邊界
    ????int?sum;?//?sum是區間元素和
    ????int?lazy;?//?lazy是懶惰標記

    ????public?Node?(int?l,?int?r,?int?sum,?int?lazy){
    ????????this.l?=?l;
    ????????this.r?=?r;
    ????????this.sum?=?sum;
    ????????this.lazy?=?lazy;
    ????}
    }投稿作者:王乙堃編輯整理:小灰需要特別說的的是,投稿的王乙堃同學年僅12歲,在讀小學六年級,能寫出這樣的文章真的很了不起!

    喜歡本文的朋友們,歡迎長按下圖關注公眾號程序員小灰,收看更多精彩內容

    給個[在看],是對小灰最大的支持! 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的l2-004 这是二叉搜索树吗? (25分)_什么是 “线段树” ?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 在线观看深夜视频 | 国产欧美在线观看不卡 | 狠狠干干 | 美女二区| 亚洲自拍偷拍第一页 | 日色网站 | 男女交性视频 | 男女草逼 | 成人在线观看一区 | 狠狠躁天天躁综合网 | 2019国产精品 | 免费在线观看亚洲 | 国产激情网 | 绿帽h啪肉np辣文 | 亚洲啪啪 | 激情黄色小视频 | 91偷拍富婆spa盗摄在线 | 操操操操操操 | 奶妈的诱惑 | 中国av免费 | 91麻豆精品91久久久久同性 | 夜夜摸夜夜操 | 天天视频天天爽 | 尤物网站在线观看 | 亚洲精品大片www | 偷拍女澡堂一区二区三区 | 蜜桃av噜噜一区二区三区麻豆 | 男人日女人b视频 | 久久久人人人 | 久久久久无码精品国产sm果冻 | 午夜在线 | 少妇毛片一区二区三区粉嫩av | 国产男女猛烈无遮挡免费视频动漫 | 成人激情视频在线播放 | 日韩精品中文字幕在线 | 欧美射图| 成人福利小视频 | 极品销魂美女少妇尤物 | 亚洲无码精品在线观看 | 黄色一级片欧美 | 天天5g天天爽免费观看 | 韩国伦理片在线观看 | 日韩av免费一区 | 无码人妻精品一区二区三区66 | gay男互凵gay男同偷精 | 男男啪啪无遮挡 | 高潮毛片无遮挡 | 日本视频色 | 熟女高潮一区二区三区 | 欧美视频在线观看一区 | 91国内在线 | 清纯唯美亚洲色图 | 欧美成人性生活片 | 欧美性受视频 | 成人福利一区 | 1024国产在线| 96在线观看 | 致命魔术电影高清在线观看 | 亚洲婷婷在线视频 | 日韩精品在线观看免费 | 一级做a爱视频 | 天天摸日日干 | 日韩欧美一区二区三区四区五区 | 成人五区 | 精品国产一区二区三区久久久蜜月 | 精品欧美一区二区三区免费观看 | 少妇又色又紧又大爽又刺激 | 老子午夜影院 | 欧美日韩精品一二三区 | 色就是色av | 性色视频在线 | 麻豆视频在线播放 | 黄色小说在线免费观看 | 97成人资源站 | 日日操夜夜干 | 福利视频一区二区三区 | 最好看的日本字幕mv视频大全 | 国产美女视频网站 | 亚洲天堂日韩av | 黑人玩弄人妻一区二区三区影院 | 涩涩在线观看 | 欧美三级韩国三级日本三斤在线观看 | 国产一二三 | 牛牛影视免费观看 | 在线观看日韩一区 | 丰满熟妇人妻中文字幕 | 亚洲一区二区蜜桃 | 黄色免费视频网站 | 成人免费自拍视频 | 美美女高清毛片视频免费观看 | 成人app在线 | 免费在线你懂的 | 午夜精品免费 | 男人天堂视频在线 | 欧美精品久久久久久久久 | 成人性视频网站 | 国产第四页 | 亚洲精品欧洲 | 亚洲欧美第一页 |