The 14th Huazhong University of Science and Technology Programming Contest I: Neat Tree Monotonic Stack

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

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.

//https://www.nowcoder.com/acm/contest/106#question


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

struct node
{
    int pos, val, pre, nxt;
    node() {}
    node(int a=0,int b=0,int c=1,int d=1):pos(a),val(b),pre(c),nxt(d){}
};
const int maxn = 1e6 + 8, INF = 0x3f3f3f3f;
int h[maxn];

intmain()
{
    int n;
    while(scanf("%d", &n) != EOF) {
        for(int i = 1;i <= n;i ++) scanf("%d", &h[i]);
        ll res1 = 0, res2 = 0;
        h[n+1] = 0;
        stack<node>st1, st2;
        for(int i = 1;i <= n + 1;i ++) {
            node now(i, h[i]);
            while(!st1.empty() && now.val <= st1.top().val) {
                node top = st1.top();
                st1.pop();
                if(!st1.empty()) st1.top().nxt += top.nxt;
                now.pre += top.pre;
                res1 += top.val * 1LL * top.pre * top.nxt;
            }
            st1.push(now);
        }
        h[n+1] = INF;
        for(int i = 1;i <= n + 1;i ++) {
            node now(i, h[i]);
            while(!st2.empty() && now.val >= st2.top().val) {
                node top = st2.top();
                st2.pop();
                if(!st2.empty()) st2.top().nxt += top.nxt;
                now.pre += top.pre;
                res2 += top.val * 1LL * top.pre * top.nxt;
            }
            st2.push(now);
        }
        printf("%lld\n", res2 - res1);
    }
    return 0;
}
/**
The meaning of the question: Given a string of numbers, calculate the sum of the maximum and minimum values ​​of all intervals.

Problem solution: The complexity of enumerating the interval l, r directly is O(N^2), but we change the way of thinking. For each number, count the number of times he is the maximum and minimum value of the interval, then perform 2 monotonic stacks, and one maintenance increment , where each number is calculated as the contribution of the minimum value of the interval. A number is extended forward as pre and backward as nxt, then its contribution as the minimum value of the interval is num*pre*nxt; Similarly, maintaining a monotonically decreasing stack, O( N) to resolve.
**/


Guess you like

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