笛卡爾樹 P2659 美麗的序列

2022-05-30 17:42:08 字數 861 閱讀 2474

tag笛卡爾樹

找出乙個序列的所有子段中子段長度乘段內元素最小值的最大值。

我們需要找出所有子段中貢獻最大的,並且乙個子段的貢獻為其長度乘區間最小值

這……不就是裸的笛卡爾樹嗎?

建出符合小根堆性質的笛卡爾樹,遞迴所有點,更新答案即可。

因為這是一道裸題,所以我記錄一下建笛卡爾樹的模板。(從oi wiki上扣的)

思路是用乙個單調棧維護一下右鏈。

偽**:

新建乙個大小為 n 的空棧。用 top 來標操作前的棧頂,k 來標記當前棧頂。

for i := 1 to n

k := top

while 棧非空 且 棧頂元素 > 當前元素

k--if 棧非空

棧頂元素.右兒子 := 當前元素

if k < top

當前元素.左兒子 := 之前棧頂元素

當前元素入棧

top := k

c++:

for(int k,i=1;i<=n;i++)

namespace star

inline void work(){

n=read();

for(int i=1;i<=n;i++) a[i]=read();

for(int k,i=1;i<=n;i++){

k=top;

while(k and a[st[k]]>a[i])k--;

if(k) rs[st[k]]=i,isrt[i]=1;

if(k為什麼你谷連帶log的做法都有就是沒人寫笛卡爾樹呀qaq

笛卡爾樹它多可愛呀~

洛谷 P2659 美麗的序列

單調棧維護區間最小值,單調遞增棧維護區間最小值,考慮當前數對答案的貢獻,不斷加入數,如果加入的數 棧頂,說明棧頂的元素對當前數所在區間是有貢獻的,同時加入當前的數。反之,若當前加入的數比棧頂元素小,那麼棧頂元素 所謂的最小值 已經失去了價值,因為他不會再對後面的區間造成影響,所以彈出棧頂,同時更新 ...

洛谷P2659 美麗的序列

題目 該題目可以用輔助陣列l i r i 來指向以data i 為最小值的左端點和右端點。然後最後列舉每個data i 尋找每個data i 的美麗值的最大值。然後輔助陣列可以用單調棧求出。include include include include include include define ...

P2659 美麗的序列 單調棧

題目 不斷求區間的最值問題,就用單調棧,記錄每個數前面第一次出現比自己小的數的小白 然後遍歷右區間對於右區間左邊,最小值是stk top 即棧頂,而stk top 1 就是stk top 左邊第乙個比stk top 小的值 那麼區間就是 stk top 1 1,i 區間最小值就是a stk top ...