題外話:bzoj2096現在找不到了。。。要交還是上洛谷。。。
給定n,k和乙個長度為n的序列,求最長的最大值最小值相差不超過k的連續序列(翻譯的很清楚)。
輸入:3 9
5 1 3 5 8 6 6 9 10
輸出:4
解釋:5 8 6 6 和 8 6 6 9都是正確的
線段樹+二分長度好像珂以做,但是只能拿80
8080
分,因為n到了3e6
3e63e
6,nlog
nlog
nnlognlogn
nlognl
ogn的做法不太珂靠。所以我們考慮強行套使用單調佇列。
(由於博主剛剛學單調佇列,所以只能強行套)
(考慮到讀者很多也是初學單調佇列,所以我站在了乙個十分好的寫部落格角度。。。)
顯然,要求最大和最小,就要維護兩個優先佇列,取名qxqx
qx和q nqn
qn。(在**中,以x
xx結尾的命名就是和求最大值有關的,以n
nn結尾就是和求最小值有關的)。qxqx
qx要保證單調遞減,那麼qxqx
qx的隊首就是最大值。同理,qnqn
qn要保證單調遞增,那麼qnqn
qn的隊首也就是最小值。以後為了敘述方便,設fxfx
fx為q xqx
qx的隊首,fnfn
fn為q nqn
qn的隊首。
經過一段時間的考慮,我們發現,fx−
fn
>
kfx-fn>k
fx−f
n>
k,那麼我們當前就一定包含了乙個不合法的區間,那麼這兩個隊首肯定有至少乙個要被刪掉。那麼,具體刪哪個呢?
答案是刪在原陣列中位置靠前的。為什麼
意會一下,或者特殊值體會法(我最喜歡用這個方法,代入乙個不那麼具有偶然性的特殊值,然後手動模擬,感受這個選擇的正確性和機智性,學資訊競賽的一定要會用這個方法)為了方便求出原陣列中的位置,在維護單調佇列的時候,直接存資料的下標,然後判fxfx
fx和f nfn
fn哪個小,刪掉對應的那個。
那麼現在就只剩下合法的區間了。如何計算這個區間的長度呢?
維護乙個pre
prepr
e,表示我們現在考慮到的左端點。初始值是1
11(忘了說了,我們特判a[1
]a[1]
a[1]
,然後後面從2
22開始考慮),在每次彈出隊首的時候要修改為隊首+1(先改再彈,不然資料不對了)。
理一下思路:
(很清楚吧)
**:
#include
#define n 3001000
#define int long long
using
namespace std;
int k,n;
int a[n]
;void
input()
}int qx[n]
,qn[n]
;int hx,tx,hn,tn;
void
solve()
else
} ans=
max(ans,i-pre+1)
;//更新答案
}printf
("%lld\n"
,ans);}
main()
洛谷 模擬題
這道題一直wa?最後看了題解終於過了 include using namespace std typedef long long ll const int ma 10005 int n int a ma 4 intmain int x,y cin x y for int i n 1 i 0 i co...
洛谷簽到題
題目描述 一天 cyx 閒得無聊,寫下了 nn 個數,每個數隻會是 11 或 22,每個數是 11 的概率和是 22 的概率都是 50 50 現在 cyx 想知道他寫的這 nn 個數的和,可他寫的數太多了,他根本算不了,所以他就想知道總和的期望值。你能告訴他麼?輸入格式 乙個整數 nn,表示 cyx...
spfa演算法(洛谷模板題)
一 概況 spfa演算法是常用的最短路演算法之一,複雜度還是非常可觀的。但缺點在於遇到稠密圖或者某些奇特的圖時可能會變慢。spfa演算法是一種單元演算法,選擇乙個出發點,計算它與其他點的最短距離。通過更新邊來不斷更新最短路。在圖論的最短路題中應用十分廣泛。二 過程 1.初始化每個節點到第乙個點的距離...