[BZOJ 1012] 最大数maxnumber
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1012
分析
- 維護后綴最大值
類似暴力的求解, A數組記錄數值, maxv記錄從當前位置向后的最大值. 每次采用從后向前的方式維護maxv數組, 如果遇到一個不需要更改的值, 也就是說新加入的元素對這個位置的maxv的值無影響, 就可以跳出循環, 因為新加入的元素對這個位置前面的值也一定沒有影響, 這是本算法里的一個最重要的優化. 不過我仍認為這個算法能過只是數據不太給力, 本質上還是O(n2)的算法吧.
單調棧
單調棧的做法又有兩種, 一種采用 STL 算法庫模板里 lower_bound 二分加速查找同時簡化代碼, 另一種采用并查集.第一種, 建立單調遞減棧, 并不是說棧里的元素是遞減的, 我們在棧里存的是數組元素的下標, 要讓下標所代表的元素值嚴格單調遞減. 每次遇到 A 操作就嘗試在棧中插入新的元素的位置下標, 注意一定要把新的元素插入無論棧最后還剩幾個元素. 遇到 Q 操作就在棧中二分查找第一個大于或等于查詢的位置的元素. 因為棧里元素所對應數組元素是遞減的, 所以該元素所對應數組元素是它及它之后最大的, 也就是我們所尋找的.
第二種, 同樣建立單調遞減棧, 意義和上面的相同. 采用并查集, 其中 p[x] = y, 表示以 x 為下標所代表的數組元素比以 y 為下標所代表的數組元素大, 最終的 p[x] 就是 x 向后的最大元素的數組下標了, 用并查集可以很方便地查出.
- 線段樹
就是普通的單點修改, 區間查詢最大值.
- 樹狀數組
同上.
小結
這是一個有多種解法的題, 各種解法復雜度不同, 編程難度也不同. 這里主要說了比較新穎的兩類解法, 而且編寫的難度很小, 注意一下細節就可以了. 平時要多注意這種用簡單數據結構就能 AC 的解法, 試著發散性思考.
代碼
維護后綴最大值 :
https://code.csdn.net/snippets/607398
單調棧-lower_bound二分 :
https://code.csdn.net/snippets/607393
單調棧-并查集 :
https://code.csdn.net/snippets/607395
總結
以上是生活随笔為你收集整理的[BZOJ 1012] 最大数maxnumber的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [BZOJ 2243] 染色
- 下一篇: [CODEVS 1087] 麦森数