線段樹的那些事

2022-05-14 16:15:16 字數 2765 閱讀 9952

作為一名蒟蒻,竟然學會了線段樹,也是神奇。。

現在就來交流一下我對線段樹的一些認識:

1.線段樹是一種資料結構,每個節點儲存乙個區間的資訊

2.可以用來優化dp、求區間最值等

3.遞迴求解,從根節點開始往下遞迴

4.用空間換時間

這是建樹函式,其中l,r表示構造的區間,lc,rc表示這個節點的左節點和右節點的編號,c為特徵值(可以替換)

將當前節點的編號記錄,然後確定區間範圍。

判斷區間大小是否為1,如果是的話就可以直接賦值了,然後return

取當前區間的mid,然後再分成左右子樹開始建樹。

最後更新當前節點的特徵值

這個是修改區間的函式:

首先判斷是不是相等,如果是的話就可以直接丟tag上然後return了

接著判斷左子樹還是右子樹要修改,左子樹遞迴

右子樹遞迴

這個是區間求和的函式:

如果當前節點與所求區間相等,那麼直接返回(記住要加上tag值)

如果當前點有tag的話,那麼就把tag往下傳,並且加入特徵值中,然後清零

接著判斷所求區間在左子樹還是右子樹中,然後return值;如果兩個都有的話,那就加起來

目前蒟蒻會的唯一優化是lazy tag,適用於區間修改等問題中

由於每次區間修改都要遞迴到葉子節點,很煩,很慢,所以乾脆就記錄下當前節點要加多少,等到呼叫的時候再加上

但是要注意query求和時需要把標記往下傳,並且加入特徵值,清零,不然之後會重複計算

題目描述

如題,已知乙個數列,你需要進行下面兩種操作:

1.將某區間每乙個數加上x

2.求出某區間每乙個數的和

輸入輸出格式

輸入格式:

第一行包含兩個整數n、m,分別表示該數列數字的個數和操作的總個數。

第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。

接下來m行每行包含3或4個整數,表示乙個操作,具體如下:

操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k

操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和

輸出格式:

輸出包含若干行整數,即為所有操作2的結果。

輸入輸出樣例

輸入樣例:

5 51 5 4 2 3

2 2 4

1 2 3 2

2 3 4

1 1 5 1

2 1 4

輸出樣例:118

20說明

時空限制:1000ms,128m

資料規模:

對於30%的資料:n<=8,m<=10

對於70%的資料:n<=1000,m<=10000

對於100%的資料:n<=100000,m<=100000

這道題目是懶標記的模板,可以用線段樹+懶標記求解

1.開始建樹,特徵值c表示當前節點的權值

2.對於詢問1,呼叫change函式,遞迴打上懶標記(需要判斷區間是否相等)

3.對於詢問2,呼叫query函式,對l~r求和,不斷遞迴,直到能夠直接求特徵值為止

my code:

#include#define maxn 100010

#define for(a,b) for(int i=a;i<=b;i++)

#define ll long long

using

namespace

std;

ll len,n,q,a[maxn],p,l,r,x;

struct

nodetr[maxn

<<2

];void

build_tree(ll l,ll r)

ll mid=l+r>>1

; tr[now].lc=len+1

;build_tree(l,mid);

tr[now].rc=len+1;build_tree(mid+1

,r);

tr[now].c=tr[tr[now].lc].c+tr[tr[now].rc].c;

return;}

void

change(ll now,ll l,ll r,ll y)

tr[now].c+=y*(r-l+1

);

if(tr[now].m>=r) change(tr[now].lc,l,r,y);

else

if(tr[now].m

else

}ll query(ll now,ll l,ll r)

if(tr[now].m>=r) return

query(tr[now].lc,l,r);

else

if(tr[now].mreturn

query(tr[now].rc,l,r);

else

return query(tr[now].lc,l,tr[now].m)+query(tr[now].rc,tr[now].m+1

,r);

}int

main()

else printf("

%lld\n

",query(1

,l,r));

}return0;

}

MySQL和B樹的那些事

一 零鋪墊 在介紹b樹之前,先來看另一棵神奇的樹 二叉排序樹 binary sort tree 首先它是一棵樹,二叉 這個描述已經很明顯了,就是樹上的一根樹枝開兩個叉,於是遞迴下來就是二叉樹了 下圖所示 而這棵樹上的節點是已經排好序的,具體的排序規則如下 從圖中可以看出,二叉排序樹組織資料時,用於查...

remap的那些事

月14日 今天還在看啟動 看到target.c這裡。先說說target.c的職責。target.c檔案包含和目標初始化相關的 如remap設定 系統時鐘設定和儲存器加速模組設定等,以及irq和fiq的異常處理空函式。好吧,這裡 看到了remap就好好查資料把它搞清楚咯!其實我前面看過這個了,只是人上...

AfxWinMain的那些事

afxwinmain函式原形如下 去掉了原來的很多沒用的注釋和累贅 cpp view plain copy print?int afxapi afxwinmain afxwininit函式 建立當前應用程式主線程 initinstance函式 內部通過create 函式來完成視窗的註冊,建立更新和顯...