単調とは何スタックですか?
単調に増加すると単調にスタックを小さく分け。(要素がインクリメントまたはスタックのデクリメントします)
たとえば、次の
要素(3)の積層後のスタック要素[2,4]内の現在の単調増加、
スタックのうち単調性を、要素(4)を維持するために
\ [[2,4] - スタック(3) - スタック(4) - [1,2,3] - スタック(0) - スタック(1)(2)(3) - [0 ] \]
単調増加スタックの主要な役割:
単調スタックに配列の各要素を維持することができる(O(N)\)\時間計算
、各要素の間隔は最大/最小値が決定され、影響範囲が間隔である[左右]。
単調最小スコープのスタックを増やします
最大値を選択の範囲を減少させるスタック単調
\(例:配列{1,2,3,2,1} \)
1 2 3 2 1
口
口口口
口口口口口
0 1 2 3 4
取得する単調な下降スタック
最大 | 区間[左、右] |
---|---|
1 | [0,0] |
2 | [0,1] |
3 | [0,4] |
2 | [3,4] |
1 | [4,4] |
メンテナンス単調スタック:
ここでは、例えば、影響の最小球を単調に増加するスタックを取ります
私たちは、添字(インデックス)がスタックにプッシュが必要です。便宜を符号化するために、我々は、単調に追加された最後のスタックのアレイを使用-INF後続のスタックを容易にするために、(最小値)。
配列になる\({1,2,3,2,1、-INF} \ )
私 | 高さ[I]をスタックに | 変更スタック | 変更スタックした後、 |
---|---|---|---|
0 | 1 | プッシュ(0) | [0] |
1 | 2 | プッシュ(1) | [0,1] |
2 | 3 | プッシュ(2) | [0,1,2] |
3 | 2 | ポップ(2)、プッシュ(3) | [0,1,3] |
4 | 1 | POP(3)、POP(1)、プッシュ(4) | [0,4] |
5 | -INF | ポップ(0)、プッシュ(4) | [] |
[左、右]右にあります:
素子高さであれば[i]がスタックからポップの要素がこれまで最小値の範囲の右側に記載されています。
[左、右]中的左:
スタック内の要素が単調にインクリメントされるので、次にスタック、スタックの素子高ポップ[s.topを()]ポップの要素よりも大きくありません。したがって、+1要素スタックの上部後に残ったインデックスの範囲がポップされ、その後、スタックをポップが空であるため、スタックケースは、空になった後に、ここで注意することはポップ、どの要素がその要素をポップよりも小さいないことを示しますポップアウト要素は、その左端のすべての要素に影響を与えます。
//单调递增栈
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long int LL;
const int MAXN = 1e6 + 1;
LL height[MAXN];
int N;
void solve(){
height[N] = -INF;
stack<int> s;
for(int i=0;i<=N;i++){
while(!s.empty() && height[s.top()] > height[i]){
int cur = s.top();
s.pop();
int _left = s.empty()?0:s.top()+1;
int _right = i-1;
cout << height[cur] << " " << _left << " " << _right << endl;
}
s.push(i);
}
}
int main() {
cin >> N;
for(int i=0;i<N;i++) cin >> height[i];
solve();
return 0;
}
//单调递减栈
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long int LL;
const int MAXN = 1e6 + 1;
LL height[MAXN];
int N;
void solve(){
height[N] = INF;
stack<int> s;
for(int i=0;i<=N;i++){
while(!s.empty() && height[s.top()] < height[i]){
int cur = s.top();
s.pop();
int _left = s.empty()?0:s.top()+1;
int _right = i-1;
cout << height[cur] << " " << _left << " " << _right << endl;
}
s.push(i);
}
}
int main() {
cin >> N;
for(int i=0;i<N;i++) cin >> height[i];
solve();
return 0;
}
テンプレート
void solve(){
//单调递增栈 -INF,递减 INF
height[N] = -INF;
stack<int> s;
for(int i=0;i<=N;i++){
//单调递增栈 >,递减 <,等号看题目
while(!s.empty() && height[s.top()] > height[i]){
int cur = s.top();
s.pop();
int _left = s.empty()?0:s.top()+1;
int _right = i-1;
cout << height[cur] << " " << _left << " " << _right << endl;
}
s.push(i);
}
}