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 ...
随机推荐
- Web(Easy UI)
HTML菜鸟教程 http://www.runoob.com/html/html-tables.html EasyUI combobox下拉多选框的实现 https://www.cnblogs.com ...
- 跟我一起学kafka(一)
从昨天下午接到新任务,要采集一个法院网站得所有公告,大概是需要采集这个网站得所有公告列表里得所有txt内容,txt文件里边是一件件赤裸裸得案件,记录这案由,原告被告等相关属性(不知道该叫什么就称之为属 ...
- mac 使用svn记录
checkout project : svn checkout svn://127.0.0.1/repository --username=username --password=password ...
- 一个不明觉厉的貌似包含很多linux资料索引的网页
http://man.lupaworld.com/content/other/Linux/linuxmanage/node108.html 貌似是个官方的doc之类的...
- UNITY 内存问题资料收集
1,https://blog.csdn.net/wetest_tencent/article/details/52130703 2,http://blog.51cto.com/13638120/208 ...
- SVN用命令行更换本地副本IP地址
1.运行svn info现连的svn信息 2.运行svn switch --relocate https://原来的地址 https://改过后的地址. svn help switch 查看switc ...
- RESTFUL 概念
1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...
- abseil的编译与使用
项目中集成了abseil.abseil提供了cmake的编译,但是缺少make install命令. 于是有了下面的的一些命令,用于生成include和lib目录. function cmake_in ...
- WWW.LoadFromCacheOrDownload
[WWW.LoadFromCacheOrDownload] static WWWLoadFromCacheOrDownload(string url, int version, uint crc = ...
- 我为什么使用Kubuntu
网上看贴,包括身边的同事.朋友,总会问的问题是:我该选择哪个Linux发行版?使用久了,就会觉得这个问题其实不是问题,纯属个人习惯而已,当你真正习惯.理解了Linux,那么任何一个发行版的优点,你都有 ...