Codeforences #334 C(div2)
2016-03-05 13:52
399 查看
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, thei-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 tiand 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
output
input
output
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 x,代表将前x个元素从小到大排序,2 x,代表将前x个元素从大到小排序,问你在m个操作完成之后,数组变为了什么。
【解题思路】这题其实是贪心思想的一个应用,首先找到最长的要操作的序列,然后找最长的之后第二长的,以此类推,找到所有可能会影响结果的有效操作,利用set进行插入删除,最后得到的数组必然就是操作完成后的数组。关键是如何找有效操作,现在开一个last数组,last[i]代表当前第i个操作是否需要操作,然后len[i]记录每一个操作序列的长度,那么last就可以根据len来更新了,这里要逆着更新,因为有效的操作肯定是在越后面发生的。
#include <bits/stdc++.h>
using namespace std;
multiset<int>s;
multiset<int>::iterator it;
const int nn = 200010;
int op[nn],ans[nn],len[nn],last[nn];
int main()
{
int n,m;
ios::sync_with_stdio();
cin.tie(0);
cin>>n>>m;
int maxlen=0;
for(int i=1; i<=n; i++)cin>>ans[i];
for(int i=1; i<=m; i++){
cin>>op[i]>>len[i];
maxlen = max(maxlen,len[i]);//维护最长的长度
}
for(int i=1; i<=maxlen; i++)s.insert(ans[i]);//将要改变的数丢进set
len[m+1]=0,last[m+1]=m+1;
for(int i=m; i>=1; i--)
{
if(len[i]>len[last[i+1]])//根据长度len更新last
{
last[i] = i;
}else{
last[i] = last[i+1];//不满住关系则用后一个last,更新这次的last.
}
}
int i=last[1];
int curlen = maxlen;//记录一下当前的最长长度,后面用得到
while(i<=m)
{
if(op[i]==1)//从大到小
{
int tmp = curlen;
int cnt = len[i]-len[last[i+1]];//上一个有效操作和这一个有效操作的差值就是需要操作的次数
while(cnt--)
{
auto it = s.end();
it--;
ans[tmp--] = *it;
s.erase(it);
}
curlen = tmp;
}
else//从小到大
{
int tmp = curlen;
int cnt = len[i]-len[last[i+1]];
while(cnt--)
{
auto it = s.begin();
ans[tmp--] = *it;
s.erase(it);
}
curlen = tmp;
}
i = last[i+1];
}
for(int i=1; i<=n; i++)cout<<ans[i]<<" ";
putchar('\n');
return 0;
}
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, thei-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 tiand 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 x,代表将前x个元素从小到大排序,2 x,代表将前x个元素从大到小排序,问你在m个操作完成之后,数组变为了什么。
【解题思路】这题其实是贪心思想的一个应用,首先找到最长的要操作的序列,然后找最长的之后第二长的,以此类推,找到所有可能会影响结果的有效操作,利用set进行插入删除,最后得到的数组必然就是操作完成后的数组。关键是如何找有效操作,现在开一个last数组,last[i]代表当前第i个操作是否需要操作,然后len[i]记录每一个操作序列的长度,那么last就可以根据len来更新了,这里要逆着更新,因为有效的操作肯定是在越后面发生的。
#include <bits/stdc++.h>
using namespace std;
multiset<int>s;
multiset<int>::iterator it;
const int nn = 200010;
int op[nn],ans[nn],len[nn],last[nn];
int main()
{
int n,m;
ios::sync_with_stdio();
cin.tie(0);
cin>>n>>m;
int maxlen=0;
for(int i=1; i<=n; i++)cin>>ans[i];
for(int i=1; i<=m; i++){
cin>>op[i]>>len[i];
maxlen = max(maxlen,len[i]);//维护最长的长度
}
for(int i=1; i<=maxlen; i++)s.insert(ans[i]);//将要改变的数丢进set
len[m+1]=0,last[m+1]=m+1;
for(int i=m; i>=1; i--)
{
if(len[i]>len[last[i+1]])//根据长度len更新last
{
last[i] = i;
}else{
last[i] = last[i+1];//不满住关系则用后一个last,更新这次的last.
}
}
int i=last[1];
int curlen = maxlen;//记录一下当前的最长长度,后面用得到
while(i<=m)
{
if(op[i]==1)//从大到小
{
int tmp = curlen;
int cnt = len[i]-len[last[i+1]];//上一个有效操作和这一个有效操作的差值就是需要操作的次数
while(cnt--)
{
auto it = s.end();
it--;
ans[tmp--] = *it;
s.erase(it);
}
curlen = tmp;
}
else//从小到大
{
int tmp = curlen;
int cnt = len[i]-len[last[i+1]];
while(cnt--)
{
auto it = s.begin();
ans[tmp--] = *it;
s.erase(it);
}
curlen = tmp;
}
i = last[i+1];
}
for(int i=1; i<=n; i++)cout<<ans[i]<<" ";
putchar('\n');
return 0;
}
相关文章推荐
- Uva1594 Ducci Sequence
- Java 多线程(三) 线程的生命周期及优先级
- JSP中getParameter与getAttribute有何区别?
- Hibernate学习——(二)细谈类功能
- 5种处理js跨域问题方法汇总
- EF(EntityFramework) 的 CodeFirst 使用指南一(创建)
- CodeForces 631C Report(找规律)
- MySQL使用内存算法
- No package 'gtk+-2.0' found (PKG_CONFIG_PATH问题) [复制链接] 0 0
- 自写网络流24题总结
- j2ee 使用db.properties连接mysql数据库
- 在水晶报表中使用Code128条形码
- 51nod 1118 机器人走方格
- 索引失效(存在索引但不使用索引)
- js跨域及解决方案
- HDU 3068 最长回文(求最长回文子串)
- 第二周项目二 标准体重
- wampum打开localhost时没有前缀,图标黄色怎么办?
- 分享一个生产环境中利用SVN上线代码的脚本
- launcher/notification icon的尺寸标准