CodeForces 631C-Report(单调栈)

题目描述:
Each month Blake gets the report containing main economic indicators of the company “Blake Technologies”. There are n commodities produced by the company. For each of them there is exactly one integer in the final report, that denotes corresponding revenue. Before the report gets to Blake, it passes through the hands of m managers. Each of them may reorder the elements in some order. Namely, the i-th manager either sorts first ri numbers in non-descending or non-ascending order and then passes the report to the manager i + 1, or directly to Blake (if this manager has number i = m).

Employees of the “Blake Technologies” are preparing the report right now. You know the initial sequence ai of length n and the description of each manager, that is value ri and his favourite order. You are asked to speed up the process and determine how the final report will look like.
输入格式
The first line of the input contains two integers n and m (1 ≤ n, m ≤ 200 000) — the number of commodities in the report and the number of managers, respectively.

The second line contains n integers ai (|ai| ≤ 109) — the initial report before it gets to the first manager.

Then follow m lines with the descriptions of the operations managers are going to perform. The i-th of these lines contains two integers ti and ri (, 1 ≤ ri ≤ n), meaning that the i-th manager sorts the first ri numbers either in the non-descending (if ti = 1) or non-ascending (if ti = 2) order.
输出格式
Print n integers — the final report, which will be passed to Blake by manager number m.
样例:
输入:
3 1
1 2 3
2 2
输出:
2 1 3

输入:
4 2
1 2 4 3
2 3
1 2
输出:
2 4 1 3
题目大意:
给定一个由n个数组成的序列和m个操作,每个操作可以使第ri位及其前面的数进行非减或者非增排列。

思路与分析:
很好的一道题,主要考察单调序列的应用。
拿到题后一开始无从下手,在自己构造了几个样例后发现题目可以简化:如果后来的操作下标ri大于前面的操作下标,那么前一次的操作就会被覆盖,如果不理解可以手动试验一下。这样,我们就可以去构造一个单调栈,栈中元素是严格单调减的,这样最后栈中剩余的操作即为需要改变的操作。
举个例子:序列为1 2 4 3,操作对为:2 3,1 2,2 4,1 2。按照下标递减原则进行进栈:

读入前两个组元素      
1 2            
2 3
读入2 4时,4比前两个下标都大,所以弹出栈中元素
2 4
最后读入1 2,栈中元素为
1 2
2 4

然后抱着简化过了的想法开始写代码,按照下标降序,每次进行sort然后取最大或者最小固定相应的几个数。结果超时了……
怎么进一步优化呢?显然我们可知,按照降序排列后的原则进行操作,后续的操作都不会影响到大于它下标ri后的操作,如图所示,假设栈中元素的下标分别是4 2 1,那么(2,4]这段序列只会被操作一次,同样相对于下标1和2,(1,2]这段序列也只会被操作一次。而这一段被操作完后的数据,根据题目要求,一定会是当前所剩余序列的最大值或者是最小值。
请添加图片描述
以我刚刚举的例子:3,4位分别取1 2 4 3序列中的两个最小值2和1;1 2位取剩余序列中两个最大值3和4,操作完后的序列为3 4 2 1。
我们可以发现,在下标ri不断减小的过程中,不断有数被确定,同时相应的序列也删掉被确定的数。也就是说我们无需对序列进行排序,只需要在刚开始进行一次排序,然后设置两个指针,用于不断取这个序列的最大值或是最小值。最后附上代码:

AC代码

#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值