Codeforces 631C Report【其他】
题意:
给定序列,将前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【其他】的更多相关文章
- Codeforces 631C. Report 模拟
C. Report time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- codeforces 631C. Report
题目链接 按题目给出的r, 维护一个递减的数列,然后在末尾补一个0. 比如样例给出的 4 21 2 4 32 31 2 递减的数列就是3 2 0, 操作的时候, 先变[3, 2), 然后变[2, 0) ...
- codeforces 631C C. Report
C. Report time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- Report CodeForces - 631C (栈)
题目链接 题目大意:给定序列, 给定若干操作, 每次操作将$[1,r]$元素升序或降序排列, 求操作完序列 首先可以发现对最后结果有影响的序列$r$一定非增, 并且是升序降序交替的 可以用单调栈维护这 ...
- CodeForces - 631C (截取法)
C. Report time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- CodeForces - 631C ——(思维题)
Each month Blake gets the report containing main economic indicators of the company "Blake Tech ...
- CF 631C report
Each month Blake gets the report containing main economic indicators of the company "Blake Tech ...
- Codeforces 631C
题意:给定n和m. 给定一个长度为n的序列,m次操作. 接下来m次操作,每行第一个数若为1,则增序排列,若为2则降序排列,第二个数是排列的范围,即从第一个数排序到第某个数. 思路: 首先,对于其中范围 ...
- CodeForces 631C Print Check
排序+构造+预处理 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm ...
随机推荐
- NBA15-16赛季半程有感
2015-2016 新赛季NBA已经开打半程又多了,这半个赛季我们见证了 勇士的三节打卡:骑士的磨合反复:马刺的老骥伏枥: 当然还有窝火的XJBD. 豪哥200W刀签约黄蜂,打出来800W刀的身价,无 ...
- div里面整齐的字体样式,所有浏览器都兼容
<div id="wenda"> <div class="table_wd" > <div class="tr1&quo ...
- php防止页面刷新代码
//代理IP直接退出 empty($_SERVER['HTTP_VIA']) or exit('Access Denied'); //防止快速刷新 session_start(); $seconds ...
- 迅为4418开发板Qt移植移动4G模块第二部分
第一部分: http://www.cnblogs.com/topeet/p/6509248.html 第二部分: 5.ping不通域名一般是DNS没有设置对造成的.在etc下有一个文件resolv.c ...
- 异常详细信息: System.ComponentModel.Win32Exception: 信号灯超时时间已到
- CAD嵌套打印(网页版)
当用户需要打印两个CAD控件的图纸时,可以采用嵌套打印实现.点击此处在线演示. 实现嵌套打印功能,首先将两个CAD控件放入网页中,js代码如下: <p align="center&qu ...
- CAD参数绘制直线(网页版)
用户可以在CAD控件视区任意位置绘制直线. 主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下: 参数 说明 DOUBLE dX1 直线的开始点x坐标 DOUBLE ...
- 打开windows服务
#include <winsvc.h> void CXXXDlg::ServiceRun() { SERVICE_STATUS ssStatus; //获得ServiceControl M ...
- VC++线程函数内怎么调用外部函数
VC++线程函数内怎么调用外部函数 1.把外部函数做成静态函数,就可以直接调用了.2.把外部函数所在的对象通过线程函数参数传到线程里面来,这样线程里可以使用此对象及其函数了.
- java解决动态的锁顺序死锁的方案
直接上代码 public class Test3 { public static Object fromAccount = new String("1"); public stat ...