单调栈
HDU 1506
用栈来维护当前位置所能向左边和右边拓展的长度
#include <iostream>
#include <cstring>
//#pragma GCC optimize(2)
#include <time.h>
#include <queue>
#include <cmath>
#include <stack>
using namespace std;
#define maxn 100005
#define inf 1e18
#define eps 0.00001
typedef long long ll;
const ll mod = 1e9+7;
ll n,arr[maxn],L[maxn],R[maxn];
int main()
{
while(cin >> n && n)
{
ll ans = 0;
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
for(ll i = 1; i <= n; i++)
cin >> arr[i];
stack<ll>A,B;
for(ll i = 1; i <= n; i++)
{
while( !A.empty() && arr[ A.top() ] >= arr[i] )
{
A.pop();
}
if( A.size() != 0 )
L[i] = A.top()+1;
else
L[i] = 1;
A.push(i);
}
for(ll i = n; i >= 1; i--)
{
while( !B.empty() && arr[ B.top() ] >= arr[i] )
{
B.pop();
}
if( B.size() != 0 )
R[i] = B.top()-1;
else
R[i] = n;
B.push(i);
}
/*for(ll i = 1; i <= n; i++)
{
cout << L[i] << " " << R[i] << endl;
}*/
for(ll i = 1; i <= n; i++)
{
ans = max(ans,( R[i]-L[i] + 1 )*arr[i] );
}
cout << ans << endl;
}
return 0;
}
单调队列
POJ 2823
双端队列,队头维护在窗口范围内的最大值或最小值
#include <iostream>
//#include <cstring>
//#pragma GCC optimize(2)
#include<time.h>
#include <queue>
#include <cmath>
using namespace std;
#define maxn 10000005
#define inf 1e18
#define eps 0.00001
typedef long long ll;
const ll mod = 1e9+7;
//const double pi = acos(-1);
ll n,m,arr[maxn];
struct Why
{
ll step,num;
Why(ll a,ll b)
{
step = a;
num = b;
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("D:\\test1.in","w",stdout);
//srand((int)time(0));
cin >> n >> m;
for(ll i = 1; i <= n; i++)
cin >> arr[i];
deque<Why>A;
for(ll i = 1; i <= n; i++)
{
while( !A.empty() && A.back().num >= arr[i] )
{
A.pop_back();
}
while( !A.empty() && i - A.front().step >= m )
{
A.pop_front();
}
A.push_back( Why(i,arr[i]) );
if(i >= m)
cout << A.front().num << " ";
}
cout << endl;
deque<Why>B;
for(ll i = 1; i <= n; i++)
{
while( !B.empty() && B.back().num <= arr[i] )
{
B.pop_back();
}
while( !B.empty() && i - B.front().step >= m )
{
B.pop_front();
}
B.push_back( Why(i,arr[i]) );
if(i >= m)
cout << B.front().num << " ";
}
cout << endl;
return 0;
}