Monotone stack application

Posted by DanArosa on Sat, 19 Feb 2022 06:42:58 +0100

As the name suggests, a monotone stack is a stack with monotone properties

Analog monotone stack

Array: 4, 5, 2, 6, 3

Monotonically increasing stack (the top of the stack is smaller than the bottom of the stack. When the element is put into the stack, if it meets the monotonicity, it will be put into the stack. If it does not meet the monotonicity, the element at the top of the stack will be put out of the stack until it meets the monotonicity):

  • If the stack is empty, 4 will be put into the stack. In the stack: 4

  • 5 is greater than the top of the stack (4), 4 out of the stack, 5 into the stack, in the stack: 5

  • 2 is less than the top of the stack (5), 2 enters the stack, and in the stack is: 5, 2

  • 6 is greater than the top of the stack (2), 2 is out of the stack, 5 is in the stack, 6 is still greater than the top of the stack (5), 5 is out of the stack, 6 is in the stack, 6 is in the stack [End]

Examples

Niuke: 14666 optimal barrier

Link: https://ac.nowcoder.com/acm/problem/14666
Source: niuke.com

The terrain of country M is uneven. Now an array is given to represent the altitude H of N mountains evenly distributed at a certain latitude in this country i , it is known that there is a sentry tower on the top of each mountain. If two sentries are located on the i and J (i < J) mountains respectively, if and only if the mountain where they are located is higher than all the mountains between themWhen, the two sentinels can monitor each other. The defensive ability of country M is the number of sentinels monitored each other. State H has long been eyeing state M. The Emperor of state H hopes that the black magicians can place a huge barrier between two mountains in state M, and the sentinels of state M cannot monitor each other through this barrier. The emperor wants you to tell him the optimal position of the barrier. You are the most trusted military division under the emperor. Now you need to help the emperor calculate the optimal position of the barrier and the maximum reduction of defensive power.

Enter description

The first line contains a positive integer T(T≤20). 
For each set of data, the first row contains a positive integer n(2≤n≤50000). 
next n A different positive integer, H1,H2,H3,...,Hn(0≤Hi≤109)Each represents the altitude of each mountain on the cross section.
(The read data is relatively large, so it is recommended to use it scanf Instead of using cin Read in)
For 60%Data, n≤500
 For 80%Data, n≤5000
 For 100%Data, n≤50000

Output description

Each group of data outputs a row, as shown in“ Case #N: X C ", n represents the nth group of data (starting from 1). X represents that placing the barrier in front of the X mountain can reduce the defensive ability of country M the most. At this time, the reduction is C. If there are multiple schemes to make the reduction amount C, the scheme corresponding to the smallest x is output.

Example 1

input

2
3
2 1 3
5
4 5 2 6 3

output

Case #1: 2 2
Case #2: 3 2

thinking

This problem was not originally written in monotone stack, but the idea is similar, so we no longer write monotone stack code

This problem first gives the values of n peaks, which we store in h [] array. Ask where the barrier is placed to reduce the defensive power the most, then we need to find the defensive power of the example in an orderly way (we can find the law only by simulating first).

We know the conditions under which the two peaks can monitor each other. During the simulation, we can find a law: when we find the right side of I, i+1,i+2... Whether the peaks can monitor each other with I, if we encounter the first case of H [i] < = H [i+k], Then i+k is the rightmost peak that I can monitor each other (understand the conditional formula of mutual monitoring. Two peaks can monitor each other only when they are higher than the peak between them)

But the data is huge, and we can't do it violently. If we traverse I from right to left, if we find the rightmost peak of I, we can first judge whether the I-1 peak is the rightmost peak of I-1. If not, If we can directly judge whether the rightmost peak of the i-th peak is higher than the i-1st peak (because the peak between the i-th peak and its own rightmost peak must be smaller than the i-th peak, they cannot be used as the rightmost peak of i-1), and so on, step by step to find the rightmost peak.

When finding the rightmost peak, you can mark the pair of mutually monitored peaks with an array, and finally find the prefix sum (equivalent to two peaks as two points, connected into a line, and the subscript and the corresponding sum is how many lines pass through here). Finally, find the maximum value and subscript

Lu code

import java.io.*;
import java.util.*;
/*Niuke 14666: optimal barrier*/
public class Main {
    /*Optimized input*/
    static StreamTokenizer cin=new StreamTokenizer(new BufferedReader(new InputStreamReader(new BufferedInputStream(System.in))));
    static PrintWriter cout=new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(System.out)));
    public static int readInt(){
        int ans=0;
        try{
            cin.nextToken();
            ans=(int)cin.nval;
        }
        catch(Exception e){}
        finally{
            return ans;
        }
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t;
        t=readInt();
        int Case=1;
        while (0!=t--){
            int n;
            n = readInt();
            int[] h=new int[n+2];
            for (int i=1;i<=n;i++){
                h[i] = readInt();/* Enter the height of the mountain 1~n */
            }

            /* After finding point i, point j (optimized here) that can monitor each other records how many lines are above */
            int[] fa = new int[n+2];/*The position of the last point that the recording point i can monitor; Convenient point i-1 traverses upward */
            for (int i = 0; i < n+2; i++) {
                fa[i]=-1;
            }
            int[] line = new int[n+2];/*The two points monitored by each other form a line, recording how many lines there are in the sky*/


            for (int i = n-1; i >=1 ; i--) {//Current peak i
                int j=i+1; // Behind the mountain j
                while (true&&j>=1&&j<=n){
                    if(h[i]<=h[j]){/* i  j You can monitor each other, and up to j now, the following can no longer monitor*/
                        fa[i]=j;
                        line[i+1]++;/*Record the starting and ending points of this route*/
                        line[j+1]--;
                        break;
                    }
                    line[i+1]++;
                    line[j+1]--;
                    j=fa[j];
                }
            }
            int maxLine=0,idx=0;
            for (int i = 2; i <=n ; i++) {
                line[i]+=line[i-1];
                if (maxLine<line[i]){
                    maxLine=line[i];
                    idx=i;
                }
            }
            System.out.println("Case #"+(Case++)+": "+idx+" "+maxLine);
        }
    }
}

Monotonically increasing stack

The idea of using monotone stack is different from traversing from left to right to find the peak on the left of the current peak that can be monitored by each other: when the stack element is larger than the stack top element, it will be out of the stack. At this time, the elements out of the stack can be monitored by each other with the stack element

Topics: data structure