雙端佇列xLIS問題 棧 最長不下降序列

2021-10-09 04:45:43 字數 1243 閱讀 2458

>解題思路

通過推算可以發現,對於原數列的第i

ii個數,一定是放在雙端佇列的中間,雙端佇列的左邊和右邊都為不下降序列(自動排除與答案無關的數),並且左邊和右邊的數在原數列中,都位於i的右邊

再加上雙端佇列插入元素的規律,又可以神奇地發現,雙端佇列右邊的數在原數列中的排列一樣,而左邊的數在原數列中是倒過來排序的(變成了最長不上公升序列),

因此,u[i]為從i開始的最長不下降序列,d[i]為從i開始的最長不上公升序列,ans=max(u[i]+d[i]-1)(去掉乙個重複的i)

u[i]與d[i]預處理,本來我是dp處理,但是o(n^2)顯然過不了,所以就要用棧+二分求最長不下降序列的方法,這樣就只有o(nlogn)了

>**

#include 

#include

#include

#include

#define n

100005

using namespace std;

int n, a[n]

, b[n]

, u[n]

, d[n]

, ans, s[n]

, t;

int main()

for(int i =

1; i <= n; i++

) b[i]

=-b[i]

;//全部轉換為負數以後,求最長不下降序列=求原數的最長不上公升序列

memset

(s,0

,sizeof

(s))

; t =0;

for(int i =

1; i <= n; i++

)for

(int i =

1; i <= n; i++

) ans =

max(ans, u[i]

+ d[i]-1

);printf

("%d"

, ans)

;return0;

}

雙端佇列xLIS問題

有 n 個數 a i 他準備將他們依次插入乙個雙端佇列 每次可以在頭或尾插入乙個元素 最後將 整個佇列從尾到頭看成乙個序列,求出最長上公升子串行的長度 他想知道 l 的最大值是多少。很簡單,考慮乙個數,構造有它的最長上公升子串行 把比他小的放他前面,比他大的放它後面 比他小的最優的就是以某乙個比他小...

數論 雙端佇列xLIS問題

對於數列中的某個點 求從它開始下降的最長子序列,這個序列將倒過來接到某點前面,成為最終的序列的前半段 求從它開始上公升的最長子序列,這個序列將倒過來接到某點後面,成為最終的序列的後半段 最終答案為某個點兩種子串行長度的和再減去1 因為統計了兩次自己 其餘的操作其實都可以省略。無法更優 include...

2020多校聯考 雙端佇列xLIS問題

觀察將乙個序列按一定方法加入到雙端佇列的性質。發現若直接在隊尾加入,則不會改變相對順序,而加入到隊頭的元素實際上是原序列的某個子串行再反過來。乾脆直接將原序列複製乙份到前面再反轉。那麼答案就是這個新序列的最長上公升子串行 考慮反轉過去後,前後對應相等的兩個元素不會同時出現在最長上公升序列中 用樹狀陣...