单调递增栈,P2659 美丽的序列

题目背景

GD是一个热衷于寻求美好事物的人,一天他拿到了一个美丽的序列。

题目描述
为了研究这个序列的美丽程度,GD定义了一个序列的“美丽度”和“美丽系数”:对于这个序列的任意一个区间[l,r],这个区间的“美丽度”就是这个区间的长度与这个区间的最小值的乘积,而整个序列的“美丽系数”就是它的所有区间的“美丽度”的最大值。现在GD想要你帮忙计算这个序列的“美丽系数”。

输入输出格式
输入格式:

第一行一个整数n,代表序列中的元素个数。 第二行n个整数a1、a2„an,描述这个序列。

输出格式:

一行一个整数,代表这个序列的“美丽系数”。

输入输出样例
输入样例#1:

3
1 2 3

输出样例#1:

4

说明

样例解释 选取区间[2,3],可以获得最大“美丽系数”为2*2=4。 数据范围 对于20%的数据,n<=2000; 对于60%的数据,n<=200000; 对于100%的数据,1<=n<=2000000,0<=ai<=2000000。 提示 你可能需要一个读入优化。

用单调递增栈做, 栈中每个元素维护一个区间的最小值, 而根据元素保存的下标可以得出区间的长度, 用结构体做加上一个top游标比用stack方便很多

#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 2000006;
int n;
//st当栈用, 用反而stack不太方便
struct node
{
	int d;
	int p;
}a[maxn], st[maxn];

int main()
{
	ios::sync_with_stdio(false);
	cin >> n;
	int top = 0;
	ll res = 0;			//保存结果的值, long long型

	for (int i = 1; i <= n; i++)
	{
		cin >> a[i].d;
		a[i].p = i;
		if (!top) st[++top] = a[i];			//栈空, 直接入栈
		else
		{
			while (st[top].d > a[i].d)			//栈顶元素更大则出栈
			{
				//出栈时要判断出栈的值维护的区间的美丽度是否更大
				res = max(res, (ll)st[top].d * (i - st[top - 1].p - 1));
				//曾以为可以用(st[top].p - st[top - 1].p + 1)但top与i不一定相差为1
				top--;
			}
		}
		st[++top] = a[i];
	}
	//遍历栈
	for (int i = 1; i <= top; i++)
		res = max(res, (ll)(n - st[i - 1].p) * st[i].d);
	cout << res << endl;
}

你可能感兴趣的:(数据结构)