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
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.
题目连接:http://codeforces.com/contest/631/problem/C
题意:一个长度为n的一位数组a,有m操作,每次操作把前r个元素进行非升序或者非降序进行排列。输出最后数组a。
思路:如果后面的操作的元素个数比前面的元素个数多或者相等,前面的操作就会无效。所以优化之后的操作就是r依次递减的。将a的前max(最大的r)位进行非降序排序Q。前一次操作为ti,ri;后一次操作为tj,rj。那么数组a的后ri-rj就确定了,如果ti==1,取剩下的Q的后ri-rj位作为a,如果ti==2,取剩下的Q的前ri-rj作为a。
代码:(Q用数组模拟,标记Q的头s和尾)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct reorder 4 { 5 int p,t,r; 6 friend bool operator < (reorder a,reorder b) 7 { 8 if(a.r!=b.r) return a.r>b.r; 9 else return a.p>b.p; 10 } 11 } reo[200100]; 12 int a[200100]; 13 deque<int>Q; ///双向队列 14 int main() 15 { 16 int i,j,n,m; 17 scanf("%d%d",&n,&m); 18 for(i=0; i<n; i++) scanf("%d",&a[i]); 19 for(i=0; i<m; i++) 20 { 21 scanf("%d%d",&reo[i].t,&reo[i].r); 22 reo[i].p=i+1; 23 } 24 sort(reo,reo+m); 25 int cou=reo[0].r,sign=reo[0].p,flag=reo[0].t; 26 sort(a,a+cou); 27 for(i=0; i<cou; i++) Q.push_back(a[i]); ///队列尾入 28 reo[m].t=0,reo[m].r=0,reo[m].p=m+1; 29 for(i=1; i<=m; i++) 30 { 31 if(reo[i].p>sign) 32 { 33 if(flag==1) 34 { 35 int gg=cou-reo[i].r; 36 while(gg--) 37 { 38 a[--cou]=Q.back(); ///队列尾元素 39 Q.pop_back(); ///尾列尾出 40 } 41 } 42 else 43 { 44 int gg=cou-reo[i].r; 45 while(gg--) 46 { 47 a[--cou]=Q.front(); ///队列头元素 48 Q.pop_front(); ///队列头出 49 } 50 } 51 sign=reo[i].p; 52 flag=reo[i].t; 53 } 54 } 55 for(i=0; i<n; i++) cout<<a[i]<<" "; 56 cout<<endl; 57 return 0; 58 }
关于运算符重载:传送门
关于STL:传送门