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.

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:

Input

3 11 2 32 2

Output

2 1 3 

Input

4 21 2 4 32 31 2

Output

2 4 1 3 

题意:

  给你一个序列,对它进行操作1,2,1:把前i个数字非降序排列。2:把前i个数非升序排列。输出排列后的序列。

题目分析:

  首先,暴力肯定是妥妥的t掉的:每次都是nlogn,m次,显然不能解决这个问题,那我们能进行什么优化呢。

  考虑一下有什么无用的操作:举个例子:如果我对前5个数进行了某种排序,再对前10个数进行某种排序,前5个排序的操作就可以直接忽略掉了。这个应该很容易想到吧。于是,我们就可以维护一个类似单调队列的数据结构:如果某个操作比另一个操作晚出现,而且排的数比早的排的数要多,前面那一个操作就可以忽略掉了。最后,我们会得到这样一些操作:

  第i个操作为对前ai个数进行某种排序,且a1>a2>a3>...>an。

  这样的话,我们继续贪心:进行完第i个操作之后,我们就可以确定ai+1+1到ai的所有数了,于是,我们通过走一遍维护的“单调队列”,就可确定每一个数了。然后就是注意一下细节就好了。

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 const int maxn=200000+10;
 5 int a[maxn];
 6 int b[maxn];
 7 int que[maxn];
 8 int c[maxn];
 9 int End;//最好大写首字母
10 int main(){
11     int n,m;
12     scanf("%d%d",&n,&m);
13     for(int i=1;i<=n;i++)
14         scanf("%d",&a[i]);
15     int js1,js2;
16     for(int i=1;i<=m;i++){
17         scanf("%d%d",&js1,&js2);
18         while(End&&que[End]<=js2)
19             End--;
20         End++;
21         que[End]=js2;
22         c[End]=js1;
23     }
24     sort(a+1,a+1+que[1]);
25     for(int i=que[1]+1;i<=n;i++)//把没有改变过的直接赋值
26         b[i]=a[i];
27     int left=1,right=que[1];
28     que[End+1]=0;//保证跑完后所有的数都被处理了
29     for(int i=1;i<=End;i++){
30         if(c[i]==2){
31             for(int j=left,j1=que[i];j<=left+que[i]-que[i+1]-1;j++,j1--)
32                 b[j1]=a[j];
33             left+=que[i]-que[i+1];
34         }
35         else{
36             for(int j=right,j1=que[i];j>=right+que[i+1]-que[i]-1;j--,j1--)
37                 b[j1]=a[j];
38             right-=que[i]-que[i+1];
39         }
40     }
41     for(int i=1;i<=n;i++)
42         printf("%d ",b[i]);
43     return 0;
44 }

  

原文地址:https://www.cnblogs.com/wish-all-ac/p/12611598.html

时间: 2024-08-05 23:34:22

Report,又是一道思维题的相关文章

北方多校 又是一道简单题

又是一道简单题 12000ms 65536K 给出一棵有根树,每次查询给出两个节点 u 和 v,假设节点 f 是u,v的最近公共祖先,请查询以 f 为根的子树中,不在 u 到 v 这条链上且标号最小的节点. 输入格式 第一行输入正整数 T(T <= 30),表示共有T组输入数据. 对于每组数据,第一行输入两个正整数 n,m(n <= 50000,m <= 50000),表示节点数和询问数,节点编号 1 到 n,其中 1 是根节点. 接下来 n - 1 行,每行输入两个正整数u,v,表示标

又是一道模拟题吧!

题目如下:This cheeseburger you don't need Description Yoda: May the Force be with you. Master Yoda is the oldest member of the Jedi Council. He conducts preparatory classes of little Younglings up to the moment they get a mentor. All Younglings adore mas

hdu2094—看似拓扑实际上是一道思维题

HDU2094  产生冠军 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2094 题意:中文题,就不解释了.题意已经非常清楚了. 这道题的看起来像是一个拓扑排序的问题实际上拓扑感觉做不了,可能可以做了吧?但是我没想到,估计也比较麻烦吧.这里介绍一种比较简单的做法,就是一种思维,如果存在冠军(所有人都可以被他打败),这个人肯定没有败过,而其他人都败过,所以我们只需要确定所有人的人数,和败者的人数(去重以后,所以需要用set,因为一个败者会败给多个人

POJ 2028 When Can We Meet? (又是一道水题)

[题目简述]:N代表有几个会员,Q代表有几个会员的时候开会才算做有效,接下来N行,每行第一个数字代表这行有M个数,说明这个会员在哪几天有时间.最后让我们求出  最快  哪天开会. [分析]:简单题,见代码. // 248K 47Ms #include<iostream> using namespace std; int M[101]; int N,Q; int main() { int m; int m1; while(1) { cin>>N>>Q; if(N == 0

一道思维题 &amp;&amp;递归改循环

思路: 比如5 2 12345--> 1245 从3开始,这时候5变成了1.剩下4512,对应1234.只需要找到现在n-1,k中的数对应原来的编号的映射.比如1-->3 是1+2 mod 5,4-->1是4+2 mod 5. 这就形成了递归. 这样递归到最后剩一个数,结果就是这个数. 这样的问题是mod n后从0开始, 解决办法1:返回时+1 #include <iostream> using namespace std; int A(int n, int k) { if

Aaronson 一道思维题

中文题目链接 Recently, Peter saw the equation x0+2x1+4x2+...+2mxm=nx0+2x1+4x2+...+2mxm=n. He wants to find a solution (x0,x1,x2,...,xm)(x0,x1,x2,...,xm) in such a manner that ∑i=0mxi∑i=0mxi is minimum and every xixi (0≤i≤m0≤i≤m) is non-negative. InputThere

每天一道Java题[11]

题目 synchronized怎么实现线程同步?请修改<每天一道Java题[10]>中的MyRunnableThread类以解决三个线程都获取到10的问题. 解答 方法一: 采用synchronized关键字包裹需要保证线程安全的代码块,来实现线程同步.语法格式为: Synchronized(expression){ //需同步的代码 } <每天一道Java题[10]>中的MyRunnableThread类修改为: package me.huangzijian; public cl

每天一道Java题[3]

问题 为什么在重写equals()方法的同时,必须重写hashCode()方法? 解答 在<每天一道Java题[2]>中,已经对hashCode()能否判断两个对象是否相等做出了解释.equals()方法与hashCode()方法的关系如下: 如果两个对象的hashCode()返回值不一样,则equals()返回的结果必为false. 如果两个对象的hashCode()返回值一样的时候,equals()返回的结果未知. 如果两个对象的equals()返回的结果为true,则两个对象的hashC

一天一道算法题---6.26---二分查找

感谢微信平台---一天一道算法题----每天多一点进步-- 好累啊  现在在用win7自带的输入法 打起来真麻烦 快点把这2天的搞完就重装了 还是直接来源于----〉 待字闺中 分析 给定一个数组A,其中有一个位置被称为Magic Index,含义是:如果i是Magic Index,则A[i] = i.假设A中的元素递增有序.且不重复,请给出方法,找到这个Magic Index.更进一步,当A中允许有重复的元素,该怎么办呢? 没有重复元素的情况 一些同学在遇到这个题目的时候,往往会觉得比较简单.