题干:

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.

Input

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.

Output

Print n integers — the final report, which will be passed to Blake by manager number m.

Examples

Input

3 1
1 2 3
2 2

Output

2 1 3 

Input

4 2
1 2 4 3
2 3
1 2

Output

2 4 1 3 

Note

In the first sample, the initial report looked like: 1 2 3. After the first manager the first two numbers were transposed: 2 1 3. The report got to Blake in this form.

In the second sample the original report was like this: 1 2 4 3. After the first manager the report changed to: 4 2 1 3. After the second manager the report changed to: 2 4 1 3. This report was handed over to Blake.

题目大意:

给定n个数和m次操作。每次操作分两种输入格式: 
1   xi 。表示将前xi个数升序排列。
2   xi 。表示将前xi个数降序排列。
让你输出操作完以后的序列。

解题报告:

首先对于不同位置的操作,显然对于第i个操作,若有第j个操作(1<=j<i)(1<=j<i) 且(xj<=xi)(xj<=xi),则第j个操作是可以无视的。这样我们就维护一个xi严格递减的单调栈,在两个邻近操作之间倒着填数就可以了,因为这些操作的特性就是,最左边的数字确定不了,但是右侧的数字一定是确定的,,最后一个操作单独处理(全填上就可以了)

超时代码1:(这个是又改过一点了?忘了答案正确与否了,直接从电脑上贴过来了)(确定了,这个是WA的)

#include<bits/stdc++.h>using namespace std;
int a[200000 + 5];
int op[200000 + 5],zxz[200000 + 5],R[200000 + 5],zz[200000 + 5];
int n,m,top;
bool cmp(const int & x,const int & y) {return x>y;
}
int main()
{scanf("%d%d",&n,&m);int maxx = 0,maxi = 1;for(int i = 1; i<=n; i++) scanf("%d",a+i);for(int i = 1; i<=m; i++) {scanf("%d%d",op+i,zxz+i);if(zxz[i] > maxx) {maxx = zxz[i];maxi = i;} }stack<int > sk;for(int i = 1; i<=m; i++) {while(!sk.empty() && zxz[sk.top()] < zxz[i]) sk.pop();if(sk.empty()) R[i] = 0;else R[sk.top()] = i;sk.push(i);}while(maxi !=0 ) {zz[++top] = maxi;maxi = R[maxi];}
//  printf("%d %d \n%d %d \n",zz[1],zz[2],zxz[zz[1]],zxz[zz[2]]);if(op[zz[top]] == 1) sort(a+1,a+zxz[zz[top]] + 1);else sort(a+1,a+zxz[zz[top]]+1,cmp);for(int i = top-1; i>=1; i--) {if(op[zz[i]] == 1) {sort(a+zxz[zz[i+1]],a + zxz[zz[i]] + 1);}else {sort(a+zxz[zz[i+1]],a + zxz[zz[i]] + 1,cmp);}}
//      for(int i = 1; i<=m; i++) printf("%d  %d\n",i,R[i]);for(int i = 1; i<=n; i++) {printf("%d%c",a[i],i == n ? '\n' : ' ');}return 0 ;
}

真*超时代码:(思路十分清晰的超时代码)

#include<bits/stdc++.h>using namespace std;
int a[200000 + 5];
int op[200000 + 5],zxz[200000 + 5],R[200000 + 5];
int n,m;
bool cmp(int x,int y) {return x>y;
}
int main()
{while(~scanf("%d%d",&n,&m)) {int maxx = 0,maxi = 1;for(int i = 1; i<=n; i++) scanf("%d",a+i);for(int i = 1; i<=m; i++) {scanf("%d%d",op+i,zxz+i);if(zxz[i] > maxx) {maxx = zxz[i];maxi = i;} }stack<int > sk;for(int i = 1; i<=m; i++) {while(!sk.empty() && zxz[sk.top()] < zxz[i]) sk.pop();if(sk.empty()) R[i] = 0;else R[sk.top()] = i;sk.push(i);}while(maxi !=0 ) {if(op[maxi] == 1) {sort(a+1,a + zxz[maxi] + 1);}else {sort(a+1,a+zxz[maxi]+1,cmp);}maxi = R[maxi];}
//      for(int i = 1; i<=m; i++) printf("%d  %d\n",i,R[i]);for(int i = 1; i<=n; i++) {printf("%d%c",a[i],i == n ? '\n' : ' ');}}return 0 ;} 

AC代码:(202ms)

#include<bits/stdc++.h>using namespace std;
int a[200000 + 5],b[200000 + 5];
int op[200000 + 5],zxz[200000 + 5],R[200000 + 5],zz[200000 + 5];
int n,m,top;
bool cmp(const int & x,const int & y) {return x>y;
}
int main()
{scanf("%d%d",&n,&m);int maxx = 0,maxi = 1;for(int i = 1; i<=n; i++) scanf("%d",a+i);for(int i = 1; i<=m; i++) {scanf("%d%d",op+i,zxz+i);if(zxz[i] > maxx) {maxx = zxz[i];maxi = i;} }stack<int > sk;//右侧临近比他小的中  最大的 for(int i = 1; i<=m; i++) {while(!sk.empty() && zxz[sk.top()] < zxz[i]) sk.pop();if(sk.empty()) R[i] = 0;else R[sk.top()] = i;sk.push(i);}while(maxi !=0 ) {zz[++top] = maxi;maxi = R[maxi];}if(op[zz[1]] == 1) sort(a+1,a+zxz[zz[1]] + 1);else sort(a+1,a+zxz[zz[1]]+1,cmp);for(int i = 1; i<=zxz[zz[1]]; i++) {b[i] = a[i];//先从小到大保存下来,最后输出a就可以了 } sort(b+1,b+zxz[zz[1]]+1);//从小到大  即我们需要填入这些数进入a数组中 int l = 1,r = zxz[zz[1]];for(int i = 1; i<top; i++) {for(int j = zxz[zz[i]]; j>=zxz[zz[i+1]]+1; j--) {if(op[zz[i]] == 1) a[j] = b[r--];else a[j] = b[l++];}}for(int j = zxz[zz[top]]; j>=1; j--) {if(op[zz[top]] == 1) a[j] = b[r--];else a[j] = b[l++];}for(int i = 1; i<=n; i++) {printf("%d%c",a[i],i == n ? '\n' : ' ');}return 0 ;
}

帮助我们深刻理解一下单调栈中存的元素的性质!!其实可以不用while那一步来存一个zz,,直接可以用栈内的元素其实就是我们想要的。

另外我们写的这个单调栈还是有点讲究的啊。。写成了R数组中存的是不严格小于的了、、、这样还是会有重复操作的,。,改成严格小于的应该会好一些?还没提交试一下、、、(试过了,WA15了,想想也确实不能这么写, 因为就是得不严格小于,也就是小于等于,因为你想啊,万一后面还有一个和你一样大的,那肯定选后面那个不选你啊,因为你这个操作肯定会被后面那个操作覆盖掉的。。。)

附:简洁的30行代码:(红名大佬Orz,不过思路还是可以学习一下的)(187ms)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,maxx,x;
int main()
{scanf("%d%d",&n,&m);vector<int> a, b(n + 2, 0), c(n + 2, 0);for(int i = 0; i<n; i++) {scanf("%d",&x);a.push_back(x);//或者直接读入cin>>a[i]; }for(int i = 1; i<=m; i++) {int x, y;scanf("%d%d", &x, &y);b[y - 1] = x;//操作 c[y - 1] = i;//操作数maxx = max(maxx, y);}vector<int> tmp = a, ans = a;sort(tmp.begin(),tmp.begin() + maxx);int l = 0, r = maxx - 1;for(int i = maxx - 1; i >= 0; i--) {if(c[i] < c[i + 1]) {c[i] = c[i + 1];b[i] = b[i + 1];}}for(int i = maxx - 1; i >= 0; i--) {if(b[i] == 2) ans[i] = tmp[l++];else ans[i] = tmp[r--];}for(int i = 0; i < n; ++i)printf("%d ", ans[i]);return 0;
}

改成了数组的形式还是187ms:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,maxx,x;
int a[200000 + 5],b[200000 + 5],c[200000 + 5],tmp[200000 + 5],ans[200000 + 5];
int main()
{scanf("%d%d",&n,&m);for(int i = 0; i<n; i++) {scanf("%d",a+i);}for(int i = 1; i<=m; i++) {int x, y;scanf("%d%d", &x, &y);b[y - 1] = x;//操作 c[y - 1] = i;//操作数maxx = max(maxx, y);}for(int i = 0; i<n; i++) {ans[i] = tmp[i] = a[i];}
//  vector<int> tmp = a, ans = a;sort(tmp,tmp+maxx);int l = 0, r = maxx - 1;for(int i = maxx - 1; i >= 0; i--) {if(c[i] < c[i + 1]) {c[i] = c[i + 1];b[i] = b[i + 1];}}for(int i = maxx - 1; i >= 0; i--) {if(b[i] == 2) ans[i] = tmp[l++];else ans[i] = tmp[r--];}for(int i = 0; i < n; ++i)printf("%d ", ans[i]);return 0;
}

【Codeforces 631C 】Report(单调栈,思维模拟)相关推荐

  1. CodeForces 631C-Report(单调栈)

    题目描述: Each month Blake gets the report containing main economic indicators of the company "Blak ...

  2. Maximum Xor Secondary CodeForces - 281D (单调栈)

    Bike loves looking for the second maximum element in the sequence. The second maximum element in the ...

  3. Skyscrapers (hard version) CodeForces - 1313C2(单调栈)

    This is a harder version of the problem. In this version n≤500000 The outskirts of the capital are b ...

  4. codeforces 547B【单调栈】

    题意: 有一个长度为n的序列,序列有长度为1...n的连续子序列, 一个连续子序列里面最小的值称作这个子序列的子序列的strength, 要求出每种长度的连续子序列的最大的strength. 思路: ...

  5. CodeForces - 1484E Skyline Photo(dp+单调栈)

    题目链接:点击查看 题目大意:给出 nnn 个建筑,每个建筑有一个高度和一个美丽值,现在要求划分为数个连续的区间,使得所有区间的贡献之和最大,其中每个区间的贡献值为,区间中高度最低的建筑物的美丽值 题 ...

  6. CodeForces - 1506G Maximize the Remaining String(单调栈+贪心)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串,假设共出现了 kkk 种字母,现在要求出一个长度为 kkk 的子序列,满足每种字母只出现一次,且字典序最大 题目分析:和之前牛客上的一道 ...

  7. 【Codeforces 549F】Yura and Developers | 单调栈、启发式合并、二分

    题目链接:https://codeforces.com/problemset/problem/549/F 题目大意: 给定一个序列和一个mod值,定义[l,r]合法当l到r的所有元素和减去其中的最大值 ...

  8. CodeForces - 817D Imbalanced Array(单调栈)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,求出所有子区间的最大值与最小值之差的和 题目分析:不难看出最大值和最小值之差的和可以拆开,拆成最大值之和与最小值之和之差,现在问题转换为如 ...

  9. CodeForces - 1407D Discrete Centrifugal Jumps(单调栈+dp)

    题目链接:点击查看 题目大意:给出 n 个大楼的高度记为 h,现在需要从第一个大楼到达第 n 个大楼,问最小步数是多少,只有满足以下条件时才能从 i 移动到 j ,设 i < j: 题目分析:无 ...

最新文章

  1. Fragment导入包的问题
  2. 在计算机术语中 将ALU控制器和,计算机组成原理试题与答案
  3. python配置核_浅谈pytorch卷积核大小的设置对全连接神经元的影响
  4. Nginx自动安装脚本
  5. java中直角三角形第三条边,Java编程,根据输入三角形的三个边边长,程序能判断三角形类型为:等边、等腰、斜角、直角三角形,求代码...
  6. FTP的连接方式(防火墙的配置)
  7. Tips--Docker常用命令
  8. 桌面制作——Wallpaper Engine+Rainmeter
  9. 服务器进bios修改启动顺序,服务器进入bios设置u盘启动
  10. 阻塞会话_使用根会话解决SQL阻塞链并进行故障排除
  11. 手机安装python模块吗_1-Python-非root用户安装Python及Python模块
  12. 兰州中川机场停车费一天多少钱,中川机场附近停车便宜
  13. 过来领你的Bug之“缺陷分析“篇
  14. 基于RFM模型的用户价值的数据分析报告
  15. Vue 动态加载子组件
  16. selenium自动化学习--截取长图的方法
  17. linux安装启动openoffice和swftools
  18. Linux 工具链 error while loading shared libraries: libgettextsrc-0.19.8.1.so 解决方法
  19. mjs无法访问ftp文件解决
  20. 36、54、72的最大公约数怎么求

热门文章

  1. Question of the Day: Microsoft | Database, Multiple Questions in One
  2. 关于CNN的权重共享,CNN到底学到了什么?
  3. HDU-5050 java大数
  4. 计算机网络基础实训精品课,《计算机网络技术》精品课程建设总结报告【荐】.doc...
  5. linux 端口tnpl,Linux和Windows端口占用情况查看
  6. python实现排列组合公式算法_朴素贝叶斯算法的Python实现
  7. echart的进阶使用(option)
  8. 1443B. Saving the City
  9. 字节跳动专家会_字节跳动招聘直播策略运营专家/经理/海外财务AR BP,ACCA优先...
  10. 量产之后计算机读不出u盘,求大神、我量产没成功然后U盘就电脑上就不显示了...