题意:

给定序列,将前a个数进行逆序或正序排列,多次操作后,求最终得到的序列。

分析:

仔细分析可以想到j<i,且rj小于ri的操作是没有意义的,对于每个i把类似j的操作删去(这里可以用multiset或者直接模拟栈的操作),最后我们会获得一个严格下降的序列即ri>rj && i<j,并且相邻的t不相等。

那么对于ri,ri+1,对[0,ri)进行排序后,又对其子序列[0,ri+1)进行相反的排序,其实只有区间[ri+1,ri−1]]内的数是按照ti规定的排序的,并且不会再改变。所以我们只需要根据ti获取[ri+1,ri−1]]之间的值即可。

那么如何获取呢?在头尾两头设两个指针,如果对应区间要求升序,则用大的数填,否则用小的数填上。

代码:

用multiset做(做题太少第一次用set的erase)

#include <cstdio>
#include<set>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 200005;
int a[maxn], b[maxn];
typedef pair<int, int>p;
#define fi first
#define se second
multiset<p>ms;
int main (void)
{
int n, m;scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
b[i] = a[i];
}
int maxr = 0;
int r, t;
multiset<p>::iterator pos;
multiset<p>::iterator rp;
for(int i = 0; i < m; i++){
scanf("%d%d", &t, &r);
p tp = p(r, t);
maxr = max(maxr, r);
rp = ms.begin();
while(rp ->first <= tp.first && rp!=ms.end())
ms.erase(rp++);
ms.insert(tp);
}
sort(b, b + maxr);
int u = maxr - 1, l = 0;
pos = ms.end();
pos--;
int cnt = 0;
while(cnt < ms.size()){
int tmp = pos->se;
cnt++;
if(cnt == ms.size()){
for(int j = (pos->fi) - 1; j >=0; j--){
if(tmp == 1) a[j] = b[u--];
else a[j] = b[l++];
}
}
else{
rp = pos--;
for(int j = (rp->fi) - 1; j >= pos->fi; j--){
if(tmp == 1) a[j] = b[u--];
else a[j] = b[l++];
}
}
}
for(int i = 0; i < n; i++){
printf("%d%c", a[i], i == n - 1?'\n':' ' );
}
return 0;
}

模拟栈的操作

#include <cstdio>
#include<algorithm>
using namespace std;//区间递减且t交叉
const int maxn = 200005;
int a[maxn], b[maxn], t[maxn], r[maxn];
int main (void)
{
int n, m;scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
b[i] = a[i];
}
int s = 0;
for(int i = 0; i < m; i++){
scanf("%d%d", &t[i], &r[i]);
while(s > 0 && r[i] >= r[s - 1]){
s--;
}
t[s] = t[i], r[s] = r[i]; s++;
}
sort(b, b + r[0]);
int l = r[0] - 1, u = 0;
r[s] = 0;
for(int i = 1; i < s + 1; i++){
for(int j = r[i - 1] - 1; j >= r[i]; j--){
if(t[i - 1] == 2) a[j] = b[u++];
else a[j] = b[l--];
}
}
//for(int i = 0; i < n; i++) printf("%d",b[i]);
for(int i = 0; i < n; i++)
printf("%d%c", a[i], i==n-1?'\n':' ');
return 0;
}

智商捉急。。。。比赛的时候就是想不到怎么保存有意义的操作, 就断定这题是一定是要用到自己没学过的数据结构。。真的要对自己自信呀~~思考思考!!

Codeforces 631C Report【其他】的更多相关文章

  1. Codeforces 631C. Report 模拟

    C. Report time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  2. codeforces 631C. Report

    题目链接 按题目给出的r, 维护一个递减的数列,然后在末尾补一个0. 比如样例给出的 4 21 2 4 32 31 2 递减的数列就是3 2 0, 操作的时候, 先变[3, 2), 然后变[2, 0) ...

  3. codeforces 631C C. Report

    C. Report time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  4. Report CodeForces - 631C (栈)

    题目链接 题目大意:给定序列, 给定若干操作, 每次操作将$[1,r]$元素升序或降序排列, 求操作完序列 首先可以发现对最后结果有影响的序列$r$一定非增, 并且是升序降序交替的 可以用单调栈维护这 ...

  5. CodeForces - 631C (截取法)

    C. Report time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  6. CodeForces - 631C ——(思维题)

    Each month Blake gets the report containing main economic indicators of the company "Blake Tech ...

  7. CF 631C report

    Each month Blake gets the report containing main economic indicators of the company "Blake Tech ...

  8. Codeforces 631C

    题意:给定n和m. 给定一个长度为n的序列,m次操作. 接下来m次操作,每行第一个数若为1,则增序排列,若为2则降序排列,第二个数是排列的范围,即从第一个数排序到第某个数. 思路: 首先,对于其中范围 ...

  9. CodeForces 631C Print Check

    排序+构造+预处理 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm ...

随机推荐

  1. fastDFS shiro权限校验 redis FreeMark页面静态化

    FastDFS是一个轻量级分布式文件系统,   使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传.下载等服务   FastDFS服务端有两个角色:跟踪器(tracker)和存储节点( ...

  2. Spring---AOP注解开发&jdbc模板&Spring事务管理

    一.AOP注解开发 此处需要回忆一遍AOP的概念.简单的来说,AOP就是利用动态代理技术,做到不触动源代码但却扩展了功能.那么就需要一个被扩展的对象和一个“新的功能”,例如说给某类的saveUser方 ...

  3. 未找到框架“.NETFramework,Version=v4.5”的引用程序集

    问题描述 一般是在编译的时候会出现这样子的问题, 问题原因: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETF ...

  4. mysql中 for update 使用

    解释: for update是在数据库中上锁用的,可以为数据库中的行上一个排它锁.当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新.例子: 比如一张表三个字段 , id(商品id), n ...

  5. B4. Concurrent JVM 锁机制(synchronized)

    [概述] JVM 通过 synchronized 关键字提供锁,用于在线程同步中保证线程安全. [synchronized 实现原理] synchronized 可以用于代码块或者方法中,产生同步代码 ...

  6. 导入.sql文件入数据库

    1.创建数据库,例如abc create database abc; 2.进入数据库 use abc 3.导入e盘下的ssh.sql文件即可 source e:\ssh.sql; 截图如下:

  7. 三、spring中高级装配(1)

    大概看了一下第三章的内容,我从项目中仔细寻找,始终没有发现哪里有这种配置,但是看完觉得spring还有这么牛B的功能啊,spring的厉害之处,这种设计程序的思想,很让我感慨... 一.环境与prof ...

  8. Android之多种Bitmap效果(4)

    1. 将图片变为圆角 2. 获取缩略图图片 3. LOMO特效 4. 旧时光特效 5. 暖意特效 6. 根据饱和度.色相.亮度调整图片 7. 添加图片外边框 8. 添加内边框 9. 创建一个缩放的图片 ...

  9. OpenMP用法大全

    OpenMP基本概念OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并 ...

  10. Oracle 学习之:ASCII,CHR函数的作用和用法

    对于ASCII以及CHR函数的用法,Oracle给出的解释是: ASCII(x)gets the ASCII value of the character X, CHR() and ASCII() h ...