Neat Tree Monotonic Stack

Link: https://www.nowcoder.com/acm/contest/106/I
Source: Niuke.com

Topic description

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.

Enter description:

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. 

Output description:

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

The problem can be transformed into the problem of how many times each number is subtracted as the minimum value and how many times each number is added as the maximum value. This makes it easy to think of monotonic stacks. .

#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];

intmain()
{
    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;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325806728&siteId=291194637