单调栈入门
单调栈:单调栈即满足单调性的栈结构,其只在一端进行进出。
以下举例及伪代码以维护一个整数的单调递增栈为例
如何使用:
插入:将一个元素插入单调栈时,为了维护栈的单调性,需要在保证将该元素插入到栈顶后整个栈满足单调性的前提下弹出最少的元素。
例如,现在有个栈中自顶向下的元素为\(1,3,5,10,30,50\),此时要插入\(20\),为了保证单调性需要依次弹出元素\(1,3,5,10\),操作后栈自顶向下变成\(20,30,50\)。
伪代码:
1 insert x 2 while( !sta.empty() && sta.top()<x ) sta.pop(); 3 sta.push(x);
使用:就是从栈顶读出来一个元素,该元素满足单调性的某一端。例如上面的例子,就是取出栈中的最小元素
板子题:https://www.luogu.com.cn/problem/P5788
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, a[3000010], f[3000010]; 4 int main() 5 { 6 stack<int> s; // 模拟用的栈 , 存的是值的下标 7 scanf("%d", &n); 8 for(int i=1; i<=n; i++){ 9 scanf("%d",&a[i]); 10 } 11 while( !s.empty() ){ 12 s.pop(); 13 } 14 s.push(1); 15 for(int i=2; i<=n; i++){ 16 while( !s.empty() ){ 17 if( a[i]>a[s.top()] ){ 18 f[s.top()] = i; 19 s.pop(); 20 }else{ 21 s.push(i); 22 break; 23 } 24 } 25 if( s.empty() ){ 26 s.push(i); 27 } 28 } 29 for(int i=1; i<=n; i++){ 30 printf("%d ",f[i]); 31 } 32 return 0; 33 }
博客参考:OI Wiki