luoguP3372 模板 線段樹 1

2022-05-05 16:45:08 字數 2581 閱讀 1526

emmm

今天gg沒講課,青青姐給我講了線段樹

(講得太好了!我們來膜一下!%%%

(然後我就是來講講我聽完後的感受的,大家重點在於誇青青姐tql

像我這樣的蒟蒻,看到線段樹的第一反應是。。。

行吧,姐給我講講唄。」

(姐太強了!

(姐太巨了!

(不愧是我姐!

然後我們就來看看線段樹是神馬東西吧~

(上網找的線段樹。感謝圖源【雖然不知道需不需要宣告,但是侵刪

先來了解一下線段樹

每個父節點包含著子節點的資訊

而每個葉子節點包含著乙個元素

我們如果要對1-5進行操作,我們可以利用線段樹進行簡化,只操作1-4這個父節點和5這個葉子節點

這裡引用luogu題解一句話:通過將整個序列分為有窮個小塊,對於要查詢的一段區間,總是可以整合成k個所分塊與m個單個元素的資訊的並集(0<=k,m<=n)

如果我們按照從左到右,自上而下的順序給樹的每乙個節點編號,第一層為1,第二層是2和3,第三層是4,5,6,7,以此類推,我們會發現,每個下標為i的父節點的左子節點下標為i * 2,右子節點下標為i * 2 + 1

了解了線段樹的基本思路,我們就可以嘗試建一棵樹了

1

void build(int l,int r,int

now)

9int mid = (l + r)>>1;//

二分優化

10 build(l,mid,now * 2);//

左右的子樹都要賦值

11 build(mid + 1,r,now * 2 + 1

);12 sum[now] = sum[now * 2] + sum[now * 2 + 1];//

當前這一層為左右子節點資訊的總和

13 }

建完樹之後要進行修改操作

1

void modify(int l,int r,int k,int now)

6 sum[now] += (long

long)(r -l + 1) * k;//

該層總共修改的值為以下子節點修改值的總和

7int mid = (l[now] + r[now])>>1;8

if(r <= mid) return modify(l,r,k,now * 2);//

完全在左子樹是時

9else

if(l >= mid + 1) modify(l,r,k,now * 2 + 1);//

在右子樹

10else

14 }

已經使用了懶標記,我們可以查詢每段區間修改後的值,並看看懶標記的下移

long

long query(int l,int r,int

now)

這樣線段樹的主體部分就寫完了

這道題是一道板子題,所以只需要把以上的**寫出來,再寫主函式就大功告成了

#includeusing

namespace

std;

const

int maxn = 100005

;int

n,m,a,b,c;

long

long sum[4 * maxn],lazy[8 * maxn],k;//

注意要開大一些

int l[4 * maxn],r[4 *maxn];

void build(int l,int r,int

now)

int mid = (l + r)>>1

; build(l,mid,now * 2

); build(mid + 1,r,now * 2 + 1

); sum[now] = sum[now * 2] + sum[now * 2 + 1];}

long

long query(int l,int r,int

now)

void modify(int l,int r,int k,int

now)

sum[now] += (long

long)(r -l + 1) *k;

int mid = (l[now] + r[now])>>1;

if(r <= mid) return modify(l,r,k,now * 2

);

else

if(l >= mid + 1) modify(l,r,k,now * 2 + 1

);

else

}int

main()

if(a == 2

) }

return0;

}

這裡還要補一句:雖然線段樹好像很快,但是它只能維護帶有結合律的資訊,比如區間max/minmax/min、sumsum、xorxor之類的,但是不帶有結合律的資訊就不能維護

emmmm

這道題就到這裡了

最後讓我們再次感謝一下青青姐的講解!

(寫這篇題解大概也是怕自己以後忘

Luogu P3372 模板 線段樹 1

線段樹1是一道線段樹的經典模板題,所涉及的線段樹基礎知識也比較全面,作為線段樹初學者 比如我 的練手題就非常合適。這道題想讓我們完成的是對乙個序列的區間修改和區間查詢。關於這兩個操作,我們要引入乙個新的東西 lazytag。關於線段樹的一些基礎寫法在這裡不再多贅述,我主要來講一下有關lazytag的...

luogu3372 線段樹模板1

題目描述 如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 輸入輸出格式 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含3或4個整數...

P3372 模板 線段樹 1

線段樹學習 這個題來看,線段樹分為建樹,更新,查詢。1.建樹 void build ll p,ll l,ll r ll mid l r 1 build lson p l,mid build rson p mid 1,r push up sum p void push up sum ll p 這段 的...