單調佇列 ACwing滑動視窗

2021-10-03 21:04:31 字數 2600 閱讀 4699

acwing 滑動視窗:

單調對列好久之前就學了,但是一直沒有深刻理解,這次又學了一下,感覺理解了點,就寫篇部落格記錄一下。

滑動視窗這題是個經典的題,可以用線段樹寫,但**量有點大,而且使用空間比較大,如果卡空間的話,顯然線段樹是過不去的,rmq在洛谷上好像是不能寫,倍增的思想可以水過時間,但這題卻過不了空間,倍增比線段樹的空間大了幾倍,所以這題過不去。

三種解題**:

rmq:acwing 上可以

#include.h>

using namespace std;

#define ll long

long

const

int maxn=

1e6;

ll n,m;

ll dma[maxn][10

],dmi[maxn][10

];ll a[maxn]

;void

init()

for(ll j=1;

(1<<=m; j++)}

}ll rmq_max

(ll l,ll r)

ll rmq_min

(ll l,ll r)

intmain()

init()

;for

(ll i=

1; m+i-

1<=n; i++)}

for(ll i=

1; m+i-

1<=n;i++)}

}

線段樹:

#include

#include

#include

using namespace std;

const

int maxn=

1e6+5;

int a[maxn]

;struct node

tr[maxn*4]

;void

pushup

(int k)

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)

;pushup

(k);

}int

query_m

(int k,

int l,

int r)

int mid=tr[k]

.l+tr[k]

.r>>1;

if(mid>=r)

else

if(midreturn

max(

query_m

(k<<

1,l,mid)

,query_m

(k<<1|

1,mid+

1,r));

}int

query_mi

(int k,

int l,

int r)

int mid=tr[k]

.l+tr[k]

.r>>1;

if(mid>=r)

else

if(midreturn

min(

query_mi

(k<<

1,l,mid)

,query_mi

(k<<1|

1,mid+

1,r));

}int

main()

build(1

,1,n);

for(

int i=

1;i+k-

1<=n;i++

)else

}for

(int i=

1;i+k-

1<=n;i++

)else

}}

單調佇列:

#include.h>

using namespace std;

//單調佇列

const

int maxn=

1e6+5;

int q[maxn]

,a[maxn]

;int n,k;

void

solv()

cout

0,tail=-1

;for

(int i=

0;iintmain()

單調佇列寫這題的空間複雜度是o(1)的,時間複雜度是o(n)的,基本上算是這題的最優解。呢麼單調佇列是如和實現的呢:

單調佇列一般用於解決區間最值問題,在解決這類問題中,單調佇列中,儲存的是下標,單調佇列的頭代表最值元素,呢麼這一題的寫法就很明顯了,先判斷頭元素在不在合法區間,如果在就不管,不在就刪去頭元素即可,之後就是維護頭元素操作,詳細看**

AcWing 滑動視窗 單調佇列

時 空限制 1s 64mb 給定乙個大小為n 106的陣列。有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動乙個位置。以下是乙個例子 該陣列為 1 3 1 3 5 3 6 7 k為3。視窗位置 最小值最大值 1 3 1 3 5 3 6 7 13...

Acwing 154 滑動視窗 單調佇列

這題和poj2823是一樣的 解析 暴力,直接對於每k個都遍歷一遍,很顯然複雜度o nk 的話行不通。對於這類問題,有乙個比較一致的思路,就是有些數字是無用的,或者用了幾次後就要被扔掉的,後續根本就排不上用場。比如有ai,aj,ax,ax ai aj,找ax左邊第乙個比它小的數,很明顯,ai壓根不需...

單調佇列 滑動視窗

nkoj 2152 description 給你乙個長度為n n 10 6 的陣列,乙個長為k的滑動的窗體從最左移至最右端,你只能見到視窗的k個數,每次窗體向右移動一位,找出窗體所包含的數字的最大和最小值,如下表所示 k的值為3 視窗位置 最小值 最大值 1 3 1 3 5 3 6 7 1 3 1 ...