Passing the Message 单调栈两次

What a sunny day! Let’s go picnic and have barbecue! Today, all kids in “Sun Flower” kindergarten are prepared to have an excursion. Before kicking off, teacher Liu tells them to stand in a row. Teacher Liu has an important message to announce, but she doesn’t want to tell them directly. She just wants the message to spread among the kids by one telling another. As you know, kids may not retell the message exactly the same as what they was told, so teacher Liu wants to see how many versions of message will come out at last. With the result, she can evaluate the communication skills of those kids.
Because all kids have different height, Teacher Liu set some message passing rules as below:

1.She tells the message to the tallest kid.

2.Every kid who gets the message must retell the message to his “left messenger” and “right messenger”.

3.A kid’s “left messenger” is the kid’s tallest “left follower”.

4.A kid’s “left follower” is another kid who is on his left,
shorter than him, and can be seen by him. Of course, a kid may have more
than one “left follower”.

5.When a kid looks left, he can only see as far as the nearest kid who is taller than him.

The definition of “right messenger” is similar to the definition of
“left messenger” except all words “left” should be replaced by words
“right”.

For example, suppose the height of all kids in the row is 4, 1, 6,
3, 5, 2 (in left to right order). In this situation , teacher Liu tells
the message to the 3rd kid, then the 3rd kid passes the message to the
1st kid who is his “left messenger” and the 5th kid who is his “right
messenger”, and then the 1st kid tells the 2nd kid as well as the 5th
kid tells the 4th kid and the 6th kid.

Your task is just to figure out the message passing route.

InputThe first line contains an integer T indicating the number of test cases, and then T test cases follows.

Each test case consists of two lines. The first line is an integer N
(0< N <= 50000) which represents the number of kids. The second
line lists the height of all kids, in left to right order. It is
guaranteed that every kid’s height is unique and less than 2^31 – 1 .OutputFor each test case, print “Case t:” at first ( t is the case
No. starting from 1 ). Then print N lines. The ith line contains two
integers which indicate the position of the ith (i starts form 1 ) kid’s
“left messenger” and “right messenger”. If a kid has no “left
messenger” or “right messenger”, print ‘0’ instead. (The position of the
leftmost kid is 1, and the position of the rightmost kid is N)Sample Input

2
5
5 2 4 3 1
5
2 1 4 3 5

Sample Output

Case 1:
0 3
0 0
2 4
0 5
0 0
Case 2:
0 2
0 0
1 4
0 0
3 0

题意 是输出每个左边(右边)比他矮的 且最高的人的高度  也就是向左(向右)找到第一个比他高的 然后他到这个人之间的最高的高度 如果没有 输出0 左右各来一遍单调栈 用flag判断是否存在

代码:
#include <iostream>
#include <cstdio>
using namespace std;

int stack[50002],l[50002],r[50002],top,a[50002],t,n,flag;

int main()
{
    scanf("%d",&t);
    for(int k=1;k<=t;k++)
    {
        top=0;
        scanf("%d",&n);
        a[0]=a[n+1]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            flag=0;
            while(top&&a[i]>=a[stack[top-1]])
            {
                flag=1;
                top--;
            }
            if(flag)l[i]=stack[top];
            else l[i]=0;
            stack[top++]=i;
        }
        top=0;///第二次从右往左用单调栈 一定要更新
        for(int i=n;i>=1;i--)
        {
            flag=0;
            while(top&&a[i]>=a[stack[top-1]])
            {
                flag=1;
                top--;
            }
            if(flag)r[i]=stack[top];
            else r[i]=0;
            stack[top++]=i;
        }
        printf("Case %d:\n",k);
        for(int i=1;i<=n;i++)
            printf("%d %d\n",l[i],r[i]);
    }
}
时间: 2024-10-06 23:07:20

Passing the Message 单调栈两次的相关文章

hdu3410 Passing the Message 单调栈

// hdu3410 Passing the Message 单调栈 // 题目意思:给你n个数,询问第i个数直到左边比它本身大的第一个数的这段 // 区间内求一个最大的值 和 直到右边比它本身大的数的第一个数的这段区间内 // 再求一个最大值. // 解题方法: // 单调栈,维护一个栈,使得站内元素单调递减即离栈顶越近,值越小 // 从左往右扫一遍,最后一个比当前元素小的数组下标(出栈的元素)就是我们要求 // 的值.然后从右往左再扫一次,就可以了. // 高大上一点,用了单调队列,只是队列

HDU 3410 &amp;&amp; POJ 3776 Passing the Message 单调队列

题意: 给定n长的数组(下标从1-n)(n个人的身高,身高各不相同 问:对于第i个人,他能看到的左边最矮的人下标.(如果这个最矮的人被挡住了,则这个值为0) 还有右边最高的人下标,同理若被挡住了则这个值为0 输出n行,每个人左右2边的下标. 单调队列,对于 front - rear 的队列(注意出队都是在rear,入队也是在rear) 当加入元素x,若这队列是单调递增的,显然q.front() <= x , 反之若>x ,则把队首元素弹掉,这样就能保持单调性. 若弹掉了队首元素,在此题中就相当

HUID 5558 Alice&#39;s Classified Message 后缀数组+单调栈+二分

http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做O(n^2) 考虑到对于每一个suffix(i),最长的LCP肯定在和他排名相近的地方取得. 按排名大小顺序枚举位置,按位置维护一个递增的单调栈,对于每一个进栈的元素,要算一算栈内元素和他的LCP最大是多少. 如果不需要输出最小的下标,最大的直接是LCP(suffix(st[top]),  suff

(单调栈)poj-2559 Largest Rectangle in a Histogram

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the

HDU 5033---Building(单调栈)

题目链接 Problem Description Once upon a time Matt went to a small town. The town was so small and narrow that he can regard the town as a pivot. There were some skyscrapers in the town, each located at position xi with its height hi. All skyscrapers loc

POJ 3415 Common Substrings(后缀数组+单调栈)

[题目链接] http://poj.org/problem?id=3415 [题目大意] 求出两个字符串长度大于k的公共子串的数目. [题解] 首先,很容易想到O(n2)的算法,将A串和B串加拼接符相连, 做一遍后缀数组,把分别属于A和B的所有后缀匹配,LCP-k+1就是对答案的贡献, 但是在这个基础上该如何优化呢. 我们可以发现按照sa的顺序下来,每个后缀和前面的串的LCP就是区间LCP的最小值, 那么我们维护一个单调栈,将所有单调递减的LCP值合并, 保存数量和长度,对每个属于B串的后缀更新

poj2796 维护区间栈//单调栈

http://poj.org/problem?id=2796 题意:给你一段区间,需要你求出(在这段区间之类的最小值*这段区间所有元素之和)的最大值...... 例如: 6 3 1 6 4 5 2 以4为最小值,向左右延伸,6 4 5  值为60....... 思路:解决完为这道题目,我才真正明白了单调栈的原理,它就是以某一个值为最小(最大)值,向这个值的两侧延伸,遇到大于它(小于它)的值,就将它延伸的范围扩大,当然,一般来说,要这样做的算法复杂度为o(n^2),但是借助栈这个玩意,维护其单调增

【NOIP数据结构专项】单调队列单调栈

[洛谷P1901 ]发射站 http://www.luogu.org/problem/show?pid=1901 题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题.由于数据很多,现只需要你帮忙计 算出接收

【单调栈】Bzoj 1012: 最大数maxnumber

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 6255  Solved: 2676[Submit][Status][Discuss] Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次