洛谷 P1886 滑動視窗 單調佇列 線段樹

2021-09-29 18:24:15 字數 2299 閱讀 9178

題目大意:給出乙個由n個數構成的序列,再給出乙個長度為k的視窗,這個視窗從第乙個下標開始一直向後移動,每次移動乙個單位,每次移動詢問一次該視窗中的最大值和最小值,最後輸出答案

題目分析:看似是乙個模擬,其實暴力模擬肯定會爆,因為涉及到區間最值問題,而且還是靜態的詢問,所以這個題目有三種方法可以解決,分別是st表,線段樹和單調佇列,因為st表我不會優化,所以有五個測試點mle了,這裡就不用那個方法了,線段樹的話空間複雜度比起st表一般是能小上5倍左右,但時間複雜度每一次查詢時要多logn的常數,所以酌情考慮吧,用線段樹的話就不會mle了,擦邊把這個題目給a了,一會也放一下**,沒什麼好說的,主要是來說一下單調佇列來做這個題目,之前只是學過單調棧,今天接觸了一下單調佇列,發現還是挺簡單的,主要原理就是用雙端佇列維護乙個嚴格遞增或嚴格遞減的序列,每次增加乙個新值的時候,將其與尾部比較,最終插入尾部,當使用的時候,是使用頭部的數值,大概就是這樣了,一會看**理解一下吧

然後這個題目還需要維護一下每個數值所代表的id,用來判斷該數值在當前區間中是否過期,若過期的話直接捨棄掉即可

當然三種方法的複雜度來比較一下吧:

st表:空間複雜度nlogn,時間複雜度:打表nlogn,查詢o(1)

線段樹:空間複雜度n*4,時間複雜度:建樹nlogn,查詢nlogn

單調佇列:空間複雜度n,時間複雜度:n

吐槽一句:這個題目本來是poj上的題目,為什麼跑來洛谷做呢,三種方法,st表mle,線段樹tle,單調佇列還不支援c++11,我:????

**:

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int inf=0x3f3f3f3f;

const int n=1e6+100;

struct node

a[n];

int ans_max[n],ans_min[n];

int main()

dequemmax;//維護最大值的單調佇列

dequemmin;//維護最小值的單調佇列

for(int i=1;i<=k-1;i++)//預處理1~k-1的值

for(int i=k;i<=n;i++)//列舉滑動視窗的末尾位置

t[n];

int a[n];

int main()

printf("\n");

l=1,r=0;

for(int i=1;i<=n;i++)

printf("\n"); }

return 0;

}

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int inf=0x3f3f3f3f;

const int n=1e6+100;

int ans1[n],ans2[n];

struct node

tree[n<<2];

void build(int k,int l,int r)

int mid=l+r>>1;

build(k<<1,l,mid);

build(k<<1|1,mid+1,r);

tree[k].mmax=max(tree[k<<1].mmax,tree[k<<1|1].mmax);

tree[k].mmin=min(tree[k<<1].mmin,tree[k<<1|1].mmin);

}int query_max(int k,int l,int r)

int query_min(int k,int l,int r)

int main()

printf("%d",ans1[1]);

for(int i=2;i+k-1<=n;i++)

printf(" %d",ans1[i]);

printf("\n%d",ans2[1]);

for(int i=2;i+k-1<=n;i++)

printf(" %d",ans2[i]);

printf("\n"); }

return 0;

}

單調佇列 洛谷P1886 滑動視窗

題目鏈結 dalao題解 題目給乙個長度為n的序列,然後給乙個值k,要求出長度為k的視窗在數列滑動過程中的最大值和最小值 圖示如下 比如給乙個長度為n 8的序列為 1 3 1 3 5 3 6 7 視窗長度是k 3 那麼視窗滑動中的 最小值就是 1 3 3 3 3 3 最大值就是 3 3 5 5 6 ...

洛谷 P1886 滑動視窗 單調佇列

現在有一堆數字共n個數字 n 10 6 以及乙個大小為k的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單位,求出每次滑動後視窗中的最大值和最小值。例如 the array is 1 3 1 3 5 3 6 7 and k 3.輸入格式 輸入一共有兩行,第一行為n,k。第二行為n個數 輸出格式 輸出...

洛谷P1886 滑動視窗 單調佇列

沒想到啊沒想到,時隔兩個月,我單調佇列又懵了 調了乙個小時,最後錯在快讀,啊!不過洛谷討論真好啊,感謝大佬!考前就不推新東西了,好好寫寫那些學過的東西 題目點這裡 我就不粘了自己點一下看吧 這題還有其他奇奇怪怪的做法,比如你可以當做rmq,用線段樹啊st表啊隨便你,不過單調佇列就可以了 單調佇列說到...