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