Neat Tree 单调栈

链接: https://www.nowcoder.com/acm/contest/106/I
来源:牛客网

题目描述

It’s universally acknowledged that there’re innumerable trees in the campus of HUST.

There is a row of trees along the East-9 Road which consists of N trees. Now that we know the height of each tree, the gardeners of HUST want to know the super-neatness of this row of trees. The neatness of a sequence of trees is defined as the difference between the maximum height and minimum height in this sequence. The super-neatness of this sequence of trees is defined as the sum of neatness of all continous subsequences of the trees.

Multiple cases please process until the end of input. There are at most 100 test cases.

输入描述:

For each case:
The first line contains an integer N represents the number of
trees.
The next line n positive integers followed, in which h i represent the
height of the tree i. 

输出描述:

For each test case, output a integer in a single line which represents the super-neatness of the row
of trees.

问题转化一下,就可以转化为求每个数作为最小值被减去了多少次,以及每个数作为最大值被加上了多少次的问题。这样就很容易想到单调栈啦。。

#include<stdio.h>
#include<string.h>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
 
const int maxn = 1e6+7;

typedef long long ll;

ll a[maxn],l[maxn],r[maxn];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
	    for(int i = 1; i <= n; i++)
	    {
	    	scanf("%lld",&a[i]);
		}
	    stack <int> st;
	    for(int i = 1; i <= n; i++)
	    {
	    	while(st.size() && a[i] < a[st.top()]) 
			    st.pop();
	    	l[i] = st.empty()? 1 : st.top()+1;
	    	st.push(i);
		}
		while(st.size())st.pop();
		for(int i = n; i >= 1; i--)
		{
			while(st.size() && a[i] <= a[st.top()])
			     st.pop();
			r[i] = st.empty()? n : st.top()-1;
			st.push(i);
		}
		ll ans = 0;
		for(int i = 1; i <= n; i++)
		{
			ans -= (ll(r[i]-i+1)*ll(i-l[i]+1)-1)*a[i];
		}
		while(st.size())st.pop();
	    for(int i = 1; i <= n; i++)
	    {
	    	while(st.size() && a[i] >= a[st.top()])
			    st.pop();
	    	l[i] = st.empty()? 1 : st.top()+1;
	    	st.push(i);
		}
	    while(st.size())st.pop();
		for(int i = n; i >= 1; i--)
		{
			while(st.size() && a[i] > a[st.top()])
			     st.pop();
			r[i] = st.empty()? n : st.top()-1;
			st.push(i);
		}
		for(int i = 1; i <= n; i++)
		{
			ans += (ll(r[i]-i+1)*ll(i-l[i]+1)-1)*a[i];
		}
		cout << ans<< endl;
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunmoonvocano/article/details/80145492