Reference from: https: //endlesslethe.com/monotone-queue-and-stack-tutorial.html#i-2
Monotonous stack
Examples of a monotonically increasing stack:
push elements are 3,4,2,6,4,5,2,3
Step i | operating | result |
---|---|---|
1 | 3 push | 3 |
2 | 3 stack into the stack 4 | 4 |
3 | 2 push | 4 2 |
4 | 2,4 pop, push 6 | 6 |
5 | 4 push | 6 4 |
6 | Stack 4, 5 into the stack | 6 5 |
7 | 2 push | 6 5 2 |
8 | 2 stack into the stack 3 | 6 5 3 |
For an element i:
- The first section left a large (smaller) than its elements;
- Determine whether this element is the most value range
- The right section is greater than its first value
- The first section to the right a distance greater than its value
- This element is to determine the most worthy of the longest interval
Code
//在“尾部”添加元素
while (r != 0 || ms[r] <= x) r--;
ms[++r] = x;
//查询栈顶元素
if (r != 0) printf("%d\n", ms[r]);
else printf("-1");
Where x can be replaced by an element onto the stack subscript x to give
Monotonous queue
Monotonically incrementing a queue Examples
queue size can not exceed 3, the elements were 3,2,8,4,5,7,6,4 enqueue
Step i | operating | result |
---|---|---|
1 | 3 into the team | 3 |
2 | 3 dequeue from the tail, the 2 teams | 2 |
3 | 8 into the team | 2 8 |
4 | 8 from the tail dequeued 4 enqueue | 2 4 |
5 | 5 into the team | 2 4 5 |
6 | 2 dequeue from the queue head, into the team 7 | 4 5 7 |
7 | 7 from the tail team, the team 6 | 4 5 6 |
8 | 6,5,4 team from the tail, the 4 teams | 4 |
- The most value can query section (not maintain large range of k)
- DP optimization
Code
//在“尾部”添加元素x
while (l != r && mq[r] <= x) r--;
mq[++r] = x;
//查询队首元素
if (l != r) printf("%d\n", mq[l+1]);
else printf("-1\n");
//弹出队首元素
if (l != r) l++;
See directly below exercises (continuous collection)
1. POJ 2823 Sliding Window
Link: POJ 2823
** that Italy: ** n and k is to give you, represents the number of elements, and the interval length, the required output starting from 1 to nk each subscripted k is the length of the minimum value output section , and the maximum output.
** Solution: ** Here write monotone queue is the index of the record, and determine what the most current index value can not within the current range, specifically looking at the code.
Code:
//#include <bits/stdc++.h>
#include <cstdio>
#include <iostream>
using namespace std;
const int maxn = 1e6+50;
int n, len, l, r;
int a[maxn];
int mq[maxn];
int main()
{
scanf("%d %d",&n, &len);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
///1 3 -1 -3 5 3 6 7
///3 2 8 4 5 7 6 4
l = 0, r = 0;
for(int i = 1; i <= n; i++){
while(l != r && a[mq[r-1]] >= a[i]){
r--;
}
mq[r++] = i;
while(mq[l] <= i - len) l++;
//for(int j = l; j < r; j++)
// cout << a[mq[j]] << " ";
//cout << endl;
if(i >= len) cout << a[mq[l]] << " ";
}
cout << endl;
l = 0, r = 0;
for(int i = 1; i <= n; i++){
while(l != r && a[mq[r-1]] <= a[i]) r--;
mq[r++] = i;
while(mq[l] <= i - len) l++;
if(i >= len) cout << a[mq[l]] << " ";
}
cout << endl;
return 0;
}
2.POJ 3250 Bad Hair Day
Links: POJ 3250
** meaning of the questions: ** n to the height of your cows, from left to right in order of priority, are looking to the right, now you ask to see the total number of cows per dairy cow can be seen to the right.
** Solution: Monotone queue simple question **
Code:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e6+60;
long long n, a[maxn];
long long h[maxn], w[maxn], cur = 0;
long long ans = 0;
const int INF = 0x3f3f3f3f;
void solve()
{
h[0] = INF+1;
for(int i = 1; i <= n+1; i++)
{
if(a[i] < h[cur])
{
h[++cur] = a[i];
w[cur] = cur-1;
}
else
{
while(a[i] >= h[cur])
{
ans += w[cur];
h[cur--] = 0;
if(cur == 0)
break;
//cur--;
}
h[++cur] = a[i];
w[cur] = cur-1;
}
if(cur == 0)
return;
}
}
int main()
{
scanf("%lld", &n);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
a[n+1] = INF;
solve();
cout << ans << endl;
return 0;
}