【bzoj2096】[Poi2010]Pilots 雙指針法+STL-set
阿新 • • 發佈:2017-08-26
sca scan sof microsoft 區間最值 bzoj turn 區間 color
題目描述
Tz又耍畸形了!!他要當飛行員,他拿到了一個飛行員測試難度序列,他設定了一個難度差的最大值,在序列中他想找到一個最長的子串,任意兩個難度差不會超過他設定的最大值。耍畸形一個人是不行的,於是他找到了你。
輸入
輸入:第一行兩個有空格隔開的整數k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz設定的最大值,n代表難度序列的長度。第二行為n個由空格隔開的整數ai(1<=ai<=2000,000,000),表示難度序列。
輸出
輸出:最大的字串長度。
樣例輸入
3 9
5 1 3 5 8 6 6 9 10
樣例輸出
4
題解
雙指針法+STL-set
考慮隨著做端點向右移動,右端點的選擇是單調不降的。所以可以使用雙指針法掃出以某個點為左端點的最長的區間。
此時需要維護區間最值,可以使用單調隊列來在線性時間內解決。當然本題也可以像我一樣使用set水過。
#include <cstdio> #include <set> using namespace std; multiset<int> s; int a[3000010]; int main() { int k , n , i , p , ans = 0; scanf("%d%d" , &k , &n); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]); for(i = p = 1 ; i <= n ; i ++ ) { while(p <= n && (s.empty() || max(*(--s.end()) , a[p]) - min(*s.begin() , a[p]) <= k)) s.insert(a[p ++ ]); ans = max(ans , p - i) , s.erase(s.find(a[i])); } printf("%d\n" , ans); return 0; }
【bzoj2096】[Poi2010]Pilots 雙指針法+STL-set