洛谷P2824 [HEOI2016/TJOI2016]排序 题解
题目在此
题目描述
在 2016 年,佳媛姐姐喜欢上了数字序列。因而她经常研究关于序列的一些奇奇怪怪的问题,现在她在研究一个难题,需要你来帮助她。
这个难题是这样子的:给出一个 1 到
n
n
n 的排列,现在对这个排列序列进行
m
m
m 次局部排序,排序分为两种:
0
l
l
l
r
r
r 表示将区间 [
l
l
l,
r
r
r] 的数字升序排序
1
l
l
l
r
r
r 表示将区间 [
l
l
l,
r
r
r] 的数字降序排序
注意,这里是对下标在区间 [ l , r l,r l,r] 内的数排序。
最后询问第 q q q 位置上的数字。
输入格式
输入数据的第一行为两个整数
n
n
n 和
m
m
m,
n
n
n 表示序列的长度,
m
m
m 表示局部排序的次数。
第二行为
n
n
n 个整数,表示 1 到
n
n
n 的一个排列。
接下来输入
m
m
m 行,每一行有三个整数
o
p
op
op,
l
l
l,
r
r
r
o
p
op
op为 0 代表升序排序,
o
p
op
op 为 1 代表降序排序,
l
l
l,
r
r
r 表示排序的区间。
最后输入一个整数
q
q
q,表示排序完之后询问的位置
输出格式
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第 q q q 位置上的数字。
输入输出样例
输入
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
输出
5
思路
这里提供一个暴力的做法,我们可以直接用桶排加max,min的优化,这个题就能水过
(记住开 O 2 O2 O2喔!)
代码
#include <cstdio>
#include <vector>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <map>
#include <ctime>
#include <set>
#define ph puts("")
#define pk putchar(' ')
using namespace std;
typedef long long ll;
template <class T>
void rd(T &x)
{
#define gc getchar()
x = 0;
char c = gc;
ll f = 1;
while (!isdigit(c)) {if (c == '-') f = -1;c = gc;}
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = gc;
x *= f;
#undef gc
}
template <class T>
void pt(T x)
{
if (x < 0)
putchar ('-'), x = (~x) + 1;
if (x > 9)
pt(x / 10);
putchar ((x % 10) ^ 48);
}
template <class T>
T Max(T x, T y)
{
return x > y ? x : y;
}
template <class T>
T Min(T x, T y)
{
return x < y ? x : y;
}
void openfile()
{
freopen("sort.in", "r", stdin);
freopen("sort.out", "w", stdout);
}
const int N = 1e5 + 5;
int n, m, a[N], q, l, r, fps;
bool bucket[N];
void low()
{
int maxx = 0, tot = l;
for (int i = l;i <= r; i++)
bucket[a[i]] = 1, maxx = Max(maxx, a[i]);
for (int i = maxx;i > 0; i--)
if (bucket[i])
{
a[tot] = i;
bucket[i] = 0;
tot++;
if (tot > r)
break;
}
}
void high()
{
int minn = N, tot = l;
for (int i = l;i <= r; i++)
bucket[a[i]] = 1, minn = Min(minn, a[i]);
for (int i = minn;i <= n; i++)
if (bucket[i])
{
a[tot] = i;
bucket[i] = 0;
tot++;
if (tot > r)
break;
}
}
int main()
{
// openfile();
rd(n), rd(m);
for (int i = 1;i <= n; i++)
rd(a[i]);
while (m--)
{
rd(fps), rd(l), rd(r);
if (fps)
low();
else
high();
}
rd(q);
pt(a[q]);
return 0;
}