題目大意:對n(1<=n<=50000)個數進行連續進行m(1<=m<=200000)次詢問:問1-n之間任意連續區間最大值和最小值之差。
之前學過線段樹,學的是模版題,求解的問題是在一段區間內任意加減,然後再詢問任意一段之區間的和。
這次的問題和之前學的模版題相同之處是:查詢的是一段連續區間的資訊。
所以之後的查詢操作,也是不斷去訪問線段樹的結點,將這些結點上的數加起來即可。
這次的問題是需要知道任意區間的最大值和最小值,因此,每個結點上應該存放的資訊是:左兒子和右兒子管轄區間所有數的最大值和最小值。
注意:這裡不能把結點資訊設計為:左兒子max或min和右兒子max或min的差。因為左兒子管轄區間的最大值最小值之差和右兒子管轄區間
最大值最小值差 不一定是整個區間的最大值最小值之差,也就是說,不滿足「區間可加性」。
一旦設計好每個結點應該存放的資訊(也就是兩個數 max和min ),每次查詢到根結點時更新當前的最大值最小值,查詢完所有結點後max-min就是答案。
#includeusingnamespace
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.求連續一段格仔的...