题干:

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. java基础相关知识
  2. linux在文档中查找内容,【Linux】用grep在文档中查找内容
  3. 手机版的python-手机版python
  4. gateway中的局部过滤器_Spring Cloud Gateway中的过滤器工厂:重试过滤器
  5. 转list_quot;quot;转 Int,{} 转 List,还有什么奇葩的 JSON 要容错?| 实战
  6. matlab busy 如何看进度,matlab solve 之后不出结果不报错,状态一直显示busy
  7. 算法-冒泡排序和快速排序
  8. BZOJ 2442 [Usaco2011 Open]修剪草坪:单调队列优化dp
  9. 【HDU5726】GCD(区间GCD查询+统计区间gcd为k的区间个数----线段树/st表+思维)
  10. 关于Vivado Simulator-ERROR: Cannot find design unit work. in library work located at xsim.dir /work
  11. 在 Word 中插入 Latex 公式
  12. 探索图片透明度叠加方式
  13. 1G ,2G, 3G,4G简单概述
  14. iphone12绿色好看 iphone12系列哪个颜色好看
  15. 【Shotcut】开源免费视频编辑软件 - 微信视频编辑利器
  16. 手机安装python的步骤_手机安装python环境
  17. 计算机公共课5——演示文稿软件 PowerPoint 2010
  18. 40vf什么意思_LED 的基本术语VF、IV、WL、IR 解释及光通量换算...
  19. 使用html video播放http-flv流
  20. 4.建模坐标系与世界坐标系

热门文章

  1. 127. Word Ladder
  2. log双线性模型log-bilinear model简单概括
  3. 华为云上可订阅F5_F5亮相华为云计算大会 解读云应用交付
  4. 1535C. Unstable String
  5. iphone复制不能全选_忘记Apple ID密码,如何直接在 iPhone 上更改?
  6. python dropna失败_使用Python部署机器学习模型的10个实践经验
  7. python123阶乘累加_使用多线程计算阶乘累加 1!+2!+3!+...+19!+20!。其中一个线程计算阶乘,另一线程实现累加并输出结果。...
  8. 网络资产管理系统_固定资产管理系统的常用操作
  9. c++ 结构体初始化_STM32入门系列-使用库函数点亮LED,LED初始化函数
  10. delphi random 六位_《蒙面唱将猜猜猜》第五季将播,六位唱将率先登场