题目描述

在 2016 年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。

这个难题是这样子的:给出一个 1 11 到 n nn 的全排列,现在对这个全排列序列进行 m mm 次局部排序,排序分为两种:

  1. (0,l,r) (0, l, r)(0,l,r) 表示将区间 [l,r] [l, r][l,r] 的数字升序排序
  2. (1,l,r) (1, l ,r)(1,l,r) 表示将区间 [l,r] [l, r][l,r] 的数字降序排序

排序后询问第 q qq 位置上的数字。

输入格式

输入数据的第一行为两个整数 n nn 和 m mm。n nn 表示序列的长度,m mm 表示局部排序的次数 (1≤n,m≤1051 \leq n, m \leq 10^51n,m105​​)。
第二行为 n nn 个整数,表示 1 11 到 n nn 的一个全排列。
接下来输入 m mm 行,每一行有三个整数 op,l,r\text{op}, l, rop,l,r, op\text{op}op 为 0 代表升序排序,op\text{op}op 为 1 代表降序排序, l,rl, rl,r 表示排序的区间。
最后输入一个整数 qqq,qqq 表示排序完之后询问的位置,1≤q≤n1 \leq q \leq n1qn。

输出格式

输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第 q qq 位置上的数字。

样例

样例输入

6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3

样例输出

5

 

二分p位置上的值

小于p的为0,大于p的为1

 线段树支持区间修改,查询区间0的个数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100010
using namespace std;
int a[maxn],n,m;
bool cmp(int x,int y){return x>y;}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    int op,l,r;
    while(m--){
        scanf("%d%d%d",&op,&l,&r);
        if(op==1) sort(a+l,a+r+1,cmp);
        if(op==0) sort(a+l,a+r+1);
    }
    int q;scanf("%d",&q);
    cout<<a[q];
} 
80分 暴力

相关文章: