模擬單調棧

2022-05-02 04:42:07 字數 2200 閱讀 1907

有n個數,每個數有權值。數學老師定義了區間價值為區間和乘上區間內的最小值。

現在要你找出有最大區間價值的區間是什麼,並輸出區間價值

輸入:每個輸入檔案只包含單組資料。

第一行乙個整數n。(1 <= n <= 100000)

第二行n個整數a_1,a_2,...,a_n。(0 <= a_i <= 1000000)

輸出:第一行輸出乙個整數,表示最大的區間價值。

第二行輸出兩個整數,表示區間的起點和終點。

保證答案唯一。

sample input:

610 1 9 4 5 9

sample output:

108

3  6

此題求區間和,以及區間的最小值,我們可以使用單調棧的思想

設定l陣列,記錄以a[i]為最小值的左邊邊界;

設定r陣列,記錄以a[i]為最小值的右邊邊界;

這樣,樣例中的l,r陣列為

位置:1 2 3 4 5 6

10 1 9 4 5 9

l        1  2 3 3 5 6

r       1  6 3 6 6 6

這樣,我們就可以通過計算 r[i]-l[i] 來得出區間的範圍,**怎麼實現呢?

以上**為模擬單調棧的核心**

由於區間價值是區間和*區間的最小值,所以我們要算出區間和,在這裡我們使用字首和

讀取資料時計算:

算出r[i]、l[i]後;

接下來的比較我就不說明了~

ac**:

#includeusing

namespace

std;

typedef

long

long

ll;const

int maxn=1e6;

ll sum[maxn];

intl[maxn],r[maxn];

inta[maxn];

intmain()

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

l[i]=l;

}for(int i=n;i>=1;i--)

r[i]=r;

}ll ans = -1

,l,r;

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

}printf(

"%lld\n

",ans);

printf(

"%lld %lld\n

",l,r);

return0;

}

view code

這道題可以學完上面之後加以強化

注意:1、計算求和區間的最大值與最小值的差=求出所有區間的最大值-所有區間的最小值==(以a[i]為最大值的區間*區間數)-(以a[i]為最小值的區間*區間數)

2、類似1 3 1出現重複值序列,使用一次 = 判斷即可,不然會減去多乙個重複值

3、陣列不要太大,容易記憶體超限!

4、int *int 會出現溢位,因此計算時最好化為 ll ~

ac**:

#includeusing

namespace

std;

typedef

long

long

ll;const

int maxn=1e6+5

;int

l[maxn],r[maxn];

inta[maxn];

intmain()

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

l[i]=l;

}for(int i=n;i>=1;i--)

r[i]=r;

}ll sum1=0

;

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

//*****************************************

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

l[i]=l;

}for(int i=n;i>=1;i--)

r[i]=r;

}for(int i=n;i>=1;i--)

printf(

"%lld\n

",sum1);

}return0;

}

view code

祝大家都能ac~

單調棧(陣列模擬)

1 n 1e5 1 數列中元素 1e9 輸入樣例 53 4 2 7 5 輸出樣例 1 3 1 2 2 思路 對於這種題顯然是可以暴力解決的,但要是想要優化一下就得思考一下。本題的意思是找到離某個數a z 最近的左邊的小於它的數 那麼這裡面就有個關係了 可以用乙個棧來存這些左邊的數,若x y z,且a...

NOIP模擬 奇襲 線段樹 單調棧

題意 給定數列,求有多少個區間滿足區間最大 1 區間最小 區間長度 滿足條件為 m ax 1 m in r 1 l ma x mi n r lmax 1 min r 1 l max min r l max 1 min r 1 l ma x mi n r lma x mi n l rmax min l...

NOIP模擬 字胡串(單調棧)

只剩5分鐘的時候打了乙個三重迴圈。完全沒想到固定左端點減少1個n。被diss了一波。對於乙個區間,如果他合法,那麼一定是有乙個非最大數在二進位制下與最大數有不同的地方,所以對於乙個數,利用單調棧記錄他作為最大數的區間 左右第乙個至少有一位與他不同的地方,利用容斥原理計算一下統計答案即可,複雜度 然後...