CodeForces - 631C ——(思维题)
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 mmanagers. 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
3 1
1 2 3
2 2
2 1 3
4 2
1 2 4 3
2 3
1 2
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个操作,每个操作由两个数组成,第一个数是操作的方式,第二个数 i 是操作的范围,若第一个数是1,则给 1-i 个数按升序排序,若第二个数是2,则给 1-i 个数按降序排列。输出所有操作完成后的序列。
思路:一道思维题,肯定不能直接一个个排序,重复操作次数太多肯定超时。
首先我们可以想到,如果下一个操作的区间比上一个要大,那么上一个操作将会是无效的,如下面两个操作:
1 5
2 8
先给前5个数按升序排列,再给前8个数按降序排列,那么第一个的升序排列就被第二个降序排列给覆盖了,所以第一个操作实际上是多余的。
所以我们可以删除那些不必要的操作来节约时间。那怎么删除呢?首先我们要找出所有操作中区间最大的操作,因为在这之前的操作都是不必要的;然后再找出这步操作之后区间最大的操作,一直如此,直到找完所有的操作。
最后我们筛选出的操作的区间就如下面的线段所示:
————————
——————
————
——
操作的区间逐渐递减,且都是不会被完全覆盖的关键操作。那具体如何筛选出关键操作:
我们首先声明一个数组t【20000】来存关键操作,数组初始化的第一个元素就是输入的第一个操作,然后遍历所有操作,如果你当前遍历到的操作,他的区间小于t数组中存下的最后一个操作,就把当前操作存入数组;否则就删除所有数组中区间比当前小的操作。因为你存储操作的过程中,只会存下比数组中操作区间小的,数组中比当前遍历到的操作小的都被删除了,所以你最后得到的一定是一个递减的关键操作序列。
但是,筛选出了关键操作还不够,还要继续优化:
假如总共给出了10个数,而最大的操作是:1 5,那么我们可以知道,答案序列的最后5个数一定和初始序列相同,因为没有操作会对后5个数进行操作,所以可以直接将后五个数存到ans数组的后5位。
接下来,看下面两个操作:
1 7
2 4
对于第一个操作,我们只需要确定5,6,7三个位置的值,因为前四个数会被下一个操作所影响,排了也是无效的。、
且确定5,6,7三个位置的值也很简单,我们先将最大操作区间内的所有数按升序排好,然后根据上面两个操作,第一个是1 7,第二个数2 4,因为第一个操作是升序,且只有5,6,7位置有效,那我们就可以在之前排好序的序列中选出最大的三个数放到ans中5,6,7的位置,然后在序列中删去这三个最大的数;如果是降序排也同理,选出最小的几个数放入ans即可。
下面看代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<climits>
#include<algorithm>
#include<stack>
#include<queue>
#define eps 1e-7
#define ll long long
#define inf 0x3f3f3f3f
#define pi 3.141592653589793238462643383279
using namespace std;
struct node{
int oper,end;
}b[]; //用来存操作
int n,m,a[],ans[];
int main()
{
cin>>n>>m;
for(int i=; i<=n; ++i)
scanf("%d",&a[i]); int sum=,t[];
scanf("%d%d",&b[].oper,&b[].end);
t[sum++] = ; //初始化关键操作为第一个操作
for(int i=; i<=m; ++i)
{
scanf("%d%d",&b[i].oper,&b[i].end); //2降序,1升序
while( b[t[sum-]].end <= b[i].end && sum > ) //如果当前操作比存下的关键操作中的最后一个还关建,那就删去
{
sum--;
}
t[sum++] = i; //将所有不如自己关键的操作删去后,将自己存入
}
for(int i=n; i>=b[t[]].end+; i--) ans[i] = a[i]; //将最大操作区间之后的数直接存入ans数组 sort(a+,a++b[t[]].end); //个最大操作区间内的数排好序 int low = ,high = b[t[]].end; //用来确定剩下的数的范围
for(int i=; i<sum; ++i)//根据两个关键操作的区间差来选择数放入ans数组
{
if(b[t[i-]].oper==)
{
for(int j=b[t[i-]].end; j>=b[t[i]].end+; --j)
ans[j] = a[high--];
}
else
{
for(int j=b[t[i-]].end; j>=b[t[i]].end+; --j)
ans[j] = a[low++];
}
}
for(int i=; i<=b[t[sum-]].end; ++i) //在剩下的最后一个操作的区间内放入剩下的数
{
if(b[t[sum-]].oper==)
ans[i] = a[high--];
else
ans[i] = a[low++];
} for(int i=; i<=n; ++i)
printf("%d%c",ans[i],i==n ? '\n' : ' ');
return ;
}
/*
10 5
1 6 9 4 3 5 12 11 2 7
1 9
2 4
2 6
1 7
2 5
*/
CodeForces - 631C ——(思维题)的更多相关文章
- Codeforces 424A (思维题)
Squats Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit Statu ...
- Vova and Trophies CodeForces - 1082B(思维题)
Vova has won nn trophies in different competitions. Each trophy is either golden or silver. The trop ...
- CodeForces - 417B (思维题)
Crash Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit Status ...
- CodeForces - 417A(思维题)
Elimination Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit ...
- B - Sonya and Exhibition CodeForces - 1004B (思维题)
B. Sonya and Exhibition time limit per test 1 second memory limit per test 256 megabytes input stand ...
- codeforces ~ 1009 B Minimum Ternary String(超级恶心的思维题
http://codeforces.com/problemset/problem/1009/B B. Minimum Ternary String time limit per test 1 seco ...
- 贪心/思维题 Codeforces Round #310 (Div. 2) C. Case of Matryoshkas
题目传送门 /* 题意:套娃娃,可以套一个单独的娃娃,或者把最后面的娃娃取出,最后使得0-1-2-...-(n-1),问最少要几步 贪心/思维题:娃娃的状态:取出+套上(2),套上(1), 已套上(0 ...
- C. Nice Garland Codeforces Round #535 (Div. 3) 思维题
C. Nice Garland time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- CodeForces - 1102A(思维题)
https://vjudge.net/problem/2135388/origin Describe You are given an integer sequence 1,2,-,n. You ha ...
随机推荐
- *(ptr++) += 123
*(ptr++) += 123; 等价于:*(ptr) = *(ptr) + 123; ptr++; 而不是:*(ptr++) = *(ptr++) + 123;程序员面试宝典p32 #include ...
- OD 实验(一) - 修改程序标题
需要修改的程序 把 I love fishc.com 修改为 hello world sch01ar 用 OD 打开程序 在程序入口处开始一直按 F8 运行程序,看看在哪里弹出对话框 运行到该地址的时 ...
- Python basic (from learn python the hard the way)
1. How to run the python file? python ...py 2. UTF-8 is a character encoding, just like ASCII. 3. ro ...
- canvas绘制矩形
canvas绘制矩形 方法 fillRect(x, y, width, height) 画一个实心的矩形 clearRect(x, y, width, height) 清除一块儿矩形区域 stroke ...
- Mellanox infinoband RDMA SDP
IPoIB Internet Protocol over InfiniBand 就是指利用物理IB网络(IB卡,线缆,交换机,更甚者IB3层交换)通过ip协议进行连接,并进行数据传输! SDP Soc ...
- Redis实战——Redis的pub/Sub(订阅与发布)在java中的实现
借鉴:https://blog.csdn.net/canot/article/details/51938955 1.什么是pub/sub Pub/Sub功能(means Publish, Subscr ...
- 塔防游戏 Day2
1. 创建炮塔选择的 UI 使用 UI -> Toggle .注意指定同一 group. 2. 创建炮台的数据类 [System.Serializable] // 序列化 public clas ...
- 浅谈Job&JobDetail
JobDetai重要属性:
- memcache分布式的高速缓存系统
http://baike.baidu.com/link?url=8v9IdWg0i_ptrTfz0APh32-SbvNUAWvXrcZM5vuJ8BrjCR2oylrieOXJ3vkSuRAq3kQV ...
- js-textarea文本换行符处理,Java后端以及js前端如何处理
方法一:后台处理 TextArea的换行符处理 TextArea文本转换为Html:写入数据库时使用 js获取了textArea的文本内容之后,器内容含有换行,空格,制表符之类的字符,但是js字符串不 ...