Passing the Message 题意 给出一组数,求每一个数左边(和右边)连续比他小的数中最大的数的位置。 思路 我们先考虑如何求它的左边连续比它小的数中最大数的位置,这就用到一种简单的数据结构了——单调栈 单调栈:单调栈实际上就是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内的元素都保持有序(单调递增或单调递减),这里我们要用到是单调递减栈(即从栈底到栈顶下标是递增的,但是数据是递减的)顺便说一下,单调递增栈(从栈底到栈顶下标是递增的,但是数据也是递增的)。 原理的话看完代码你品你细品~
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
#define pi acos(-1.0)
#define e exp(1.0)
#define pb push_back
#define mk make_pair
#define fir first
#define sec second
#define scf scanf
#define prf printf
typedef pair< ll, ll> pa;
const ll INF= 0x3f3f3f3f3f3f3f3f ;
const int MAX_N= 5e4 + 7 ;
int T, N;
int hei[ MAX_N] , resl[ MAX_N] , resr[ MAX_N] ;
stack< int > S;
int main ( )
{
ios: : sync_with_stdio ( false) ;
cin>> T;
int i, j, k= 0 ;
while ( T-- ) {
cin>> N;
for ( i= 1 ; i<= N; i++ ) {
cin>> hei[ i] ;
}
while ( ! S. empty ( ) )
S. pop ( ) ;
for ( i= 1 ; i<= N; i++ ) {
resl[ i] = 0 ;
while ( ! S. empty ( ) && hei[ S. top ( ) ] < hei[ i] ) {
resl[ i] = S. top ( ) ;
S. pop ( ) ;
}
S. push ( i) ;
}
while ( ! S. empty ( ) )
S. pop ( ) ;
for ( i= N; i; i-- ) {
resr[ i] = 0 ;
while ( ! S. empty ( ) && hei[ S. top ( ) ] < hei[ i] ) {
resr[ i] = S. top ( ) ;
S. pop ( ) ;
}
S. push ( i) ;
}
cout<< "Case " << ++ k<< ":" << endl;
for ( i= 1 ; i<= N; i++ ) {
cout<< resl[ i] << ' ' << resr[ i] << endl;
}
}
return 0 ;
}