题目
Each month Blake gets the report containing main economic indicators of the company “Blake Technologies”. There are n n 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 m m managers. Each of them may reorder the elements in some order. Namely, the i i i -th manager either sorts first ri r_{i} ri numbers in non-descending or non-ascending order and then passes the report to the manager i+1 i+1 i+1 , or directly to Blake (if this manager has number i=m i=m i=m ).
Employees of the “Blake Technologies” are preparing the report right now. You know the initial sequence ai a_{i} ai of length n n n and the description of each manager, that is value ri r_{i} 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 n n and m m m ( 1<=n,m<=200000 1<=n,m<=200000 1<=n,m<=200000 ) — the number of commodities in the report and the number of managers, respectively.
The second line contains n n n integers ai a_{i} ai ( ∣ai∣<=109 |a_{i}|<=10^{9} ∣ai∣<=109 ) — the initial report before it gets to the first manager.
Then follow m m m lines with the descriptions of the operations managers are going to perform. The i i i -th of these lines contains two integers ti t_{i} ti and ri r_{i} ri (, 1<=ri<=n 1<=r_{i}<=n 1<=ri<=n ), meaning that the i i i -th manager sorts the first ri r_{i} ri numbers either in the non-descending (if ti=1 t_{i}=1 ti=1 ) or non-ascending (if ti=2 t_{i}=2 ti=2 ) order.
输出格式
Print n n n integers — the final report, which will be passed to Blake by manager number m m m .
题意翻译
给定n个整数组成的序列和m个操作,每个操作给定ti和ri,操作分为两种:
ti为1,则将前ri个数按照连续不减序(从小到大)排列;
ti为2,则将前ri个数按照连续不增序(从大到小)排列。
求m次操作过后的序列。
输入输出样例
输入 #1
3 1
1 2 3
2 2
输出 #1
2 1 3
输入 #2
4 2
1 2 4 3
2 3
1 2
输出 #2
2 4 1 3
说明/提示
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.
洛谷链接
链接: 点这里.
我的想法
1.使用【单调栈(递增的)】,存放m条命令【因为后面的命令如果比前面的要小或者等于,那么后面的就会覆盖前面的。特别的,如果后面的和前面的执行命令相同(都是递增排序,或者都是递减排序),那么也是一样的效果,可以放弃】
2.将栈内存放的元素从底向上取出,并将初始数组进行排序(只排序到栈中存放的最高的),然后再将他们按照栈中的命令来做。比如高度为[7,6,3,2,1],命令为[1,2,1,2,1]总的n为10;那么[8,10]的不变,[7,7]的命令为1,就从后顺序读入,[6,4]的命令为2,就要从前往后读…
tips:如果使用代码中的方法,第二步的最后一部分的时间复杂度大概为O(n),可能是,错了请指正,我的想法是,外面一层循环,内部循环是连续的。而使用reverse直接写的话了,会超时,但好像也不是很多。
代码
#include<algorithm>
#include<cstring>
#include<cstdio>
/*
我的想法:每条指令的第二个数字,代表高度。
使用单调栈处理m条指令,是得到一个高度递减的序列,
而且该序列相邻的两条指令,必然是不同的commander
试一试吧,感觉题解的时间复杂度和我的也差不多
first: Time Limite Exceed on Test 26 (可能是递归造成的?)
second: (使用了非递归的方式)同上,与递归无关 .使用手写stack?
third:使用了手写stack,依然超时...
4 : cin >> scanf...
5: Node >> []*2
6: 最后,如果用reverse,会比这么写慢一点,tmd
*/
using namespace std;
const int N = 2e5 + 1e3;
int heigth[N] , com[N];
int n , m , ini[N] , sta[N] , top , res[N];
bool cmp1(int a, int b){
return a<b;
}
bool cmp2(int a, int b){
return a>b;
}
int main(){
int i , j , tem , cnt = 0;
int h , c;
scanf("%d%d",&n,&m);
for(i = 1 ; i <= n ; i ++ ){
scanf("%d",&ini[i]);
res[i] = ini[i];
}
for(i = 1 ; i <= m ; i ++ ){
scanf("%d%d",&com[i],&heigth[i]);
if(!top || heigth[i] < heigth[sta[top-1]]){
if(top &&com[sta[top-1]] == com[i]) continue;
sta[top++] = i;
}else{
while(top && heigth[i] >= heigth[sta[top-1]]){
sta[--top] = 0;
}
if(!top || com[i] != com[sta[top-1]] ){
sta[top++] = i;
}
}
}
int rr = heigth[sta[0]] , ll = 1;
sta[top] = 0;
sort(ini+1 , ini+1+heigth[sta[0]]);
for(i = 0 ; i < top ; i ++ ){
for(j = heigth[sta[i]] ; j > heigth[sta[i+1]] ; j -- ){
if(com[sta[i]] == 1) res[j] = ini[rr--];
else res[j] = ini[ll++];
}
}
for(i = 1 ; i <= n ; i ++){
printf("%d " , res[i]);
}
return 0;
}