原題的題意可以理解為求所有子區間的最大值減去最小值的和。
即所有子區間的最大值減去最小值。
我們考慮用單調棧求解。
維護兩個陣列 l[i] ,r[i]。表示當前元素作為最大值所能到達的左邊和右邊的下標是多少(當前元素作為最值),用單調棧維護。
先正著維護左區間,再倒著維護右區間。
維護時的操作:當前元素大於前乙個元素時,下標存上乙個l[i]的下標,一直迴圈下去,直到當前數小於前面比較的數,左區間維護成功。右區間的維護是同樣的道理。
維護最小值只需要把原來陣列全部變成相反數,可以找到最小值。
求和:排列組合的思想,當前數作為最大值,左邊到l[i] ,右邊到r[i],左邊的情況有i-l[i]種,右邊情況有r[i]-i種,相乘即可。
#include
using
namespace std;
#define int long long
int a[
1<<17]
;int l[
1<<17]
,r[1
<<17]
;int n;
intsolve()
for(
int i=n;i;i--
)int ans=0;
for(
int i=
1;i<=n;i++
)return ans;
}signed
main()
return0;
}
區區區間間間(單調棧)
時間限制 c c 1秒,其他語言2秒 空間限制 c c 32768k,其他語言65536k 第一行輸入資料組數t 對於每組資料,第一行為乙個整數n,表示序列長度 接下來一行有n個數,表示序列內的元素 對於每組資料,輸出乙個整數表示答案 示例1334 2351 8439 202815 110519 1...
牛客 區區區間間間 單調棧
定義 v max a i a j l i,j r 求 sum sum v 轉換 sum sum max a i sum sum min a i 因此這裡就轉換成了求乙個區間內的最大和最小值。我們考慮最大值的區間覆蓋,這裡就形成了乙個單調棧了,在當前取值的左右兩側都是遞增的,因此我們得到當前值得區間覆...
每日一題 單調數列
如果陣列是單調遞增或單調遞減的,那麼它是單調的。如果對於所有 i j,a i a j 那麼陣列 a 是單調遞增的。如果對於所有 i j,a i a j 那麼陣列 a 是單調遞減的。當給定的陣列 a 是單調陣列時返回 true,否則返回 false。示例 1 輸入 1,2,2,3 輸出 true 示例...