10 25演算法訓練 裸線段樹

2022-06-05 00:54:10 字數 1184 閱讀 7595

題目大意:對n(1<=n<=50000)個數進行連續進行m(1<=m<=200000)次詢問:問1-n之間任意連續區間最大值和最小值之差。

之前學過線段樹,學的是模版題,求解的問題是在一段區間內任意加減,然後再詢問任意一段之區間的和。

這次的問題和之前學的模版題相同之處是:查詢的是一段連續區間的資訊。

所以之後的查詢操作,也是不斷去訪問線段樹的結點,將這些結點上的數加起來即可。   

這次的問題是需要知道任意區間的最大值和最小值,因此,每個結點上應該存放的資訊是:左兒子和右兒子管轄區間所有數的最大值和最小值。

注意:這裡不能把結點資訊設計為:左兒子max或min和右兒子max或min的差。因為左兒子管轄區間的最大值最小值之差和右兒子管轄區間

最大值最小值差  不一定是整個區間的最大值最小值之差,也就是說,不滿足「區間可加性」。  

一旦設計好每個結點應該存放的資訊(也就是兩個數 max和min ),每次查詢到根結點時更新當前的最大值最小值,查詢完所有結點後max-min就是答案。

#includeusing

namespace

std;

struct

node;

const

int maxl=50000

;node sum[maxl

<<2

];int

a[maxl];

intmax,min;

void pushup(int

rt)

void build(int l,int r,int

rt)

int m=(l+r)>>1

;

build(l,m,rt

<<1

);

build(m+1,r,rt<<1|1

);

pushup(rt); }

void query(int l,int r,int l,int r,int

rt)

int m=(l+r)>>1

;

if(l <= m) query(l,r,l,m,rt<<1

);

if(r > m) query(l,r,m+1,r,rt<<1|1

);

}int

main()

}return0;

}

線段樹訓練

d hdu6703 題意 給乙個長度為n且互不相同的陣列。有m個操作,操作1是給a pos 加上1000000,操作2是查詢在1 r沒有出現過同時大於k的值,並使其最小。一種做法就是權值線段樹,每個節點維護該權值的下標,那麼原題就轉化為查詢 k,n 範圍內大於r的值,位置盡量靠左,即可使答案最小。i...

演算法訓練 操作格仔 線段樹

問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m。接下來一行n個整數表示n個格仔的初始權值。接下來m行,每行3個整數p...

藍橋杯演算法訓練 格仔操作 線段樹

這題設計最基本的線段樹應用,同時考察區間和與區間最值,我採用乙個造樹函式,乙個更新函式和兩個查詢查詢函式,兩個查詢函式分別返回區間和與區間最大值。問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的...