题目描述

在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q位置上的数字。

输入输出格式

输入格式:

输入数据的第一行为两个整数n和m。n表示序列的长度,m表示局部排序的次数。1 <= n, m <=
10^5第二行为n个整数,表示1到n的一个全排列。接下来输入m行,每一行有三个整数op, l, r,
op为0代表升序排序,op为1代表降序排序, l, r 表示排序的区间。最后输入一个整数q,q表示排序完之后询问的位置, 1 <= q
<= n。1 <= n <= 10^5,1 <= m <= 10^5

输出格式:

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

输入输出样例

输入样例#1:
复制

6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
输出样例#1: 复制

5

说明

河北省选2016第一天第二题。原题的时限为6s,但是洛谷上是1s,所以洛谷的数据中,对于30%的数据,有 n,m<=1000,对于100%的数据,有 n,m<=30000


二分答案的大小mid。

大于等于mid设为1,其余的设为0.

这样可以用线段树实现$\large O(logN)$排序。

这样排序结束之后如果位置p是1, 就增大l, 否则减小r。


#include <iostream>
#include <cstdio>
using namespace std;
#define reg register
inline int read() {
int res = ;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) res=(res<<)+(res<<)+(ch^), ch=getchar();
return res;
}
#define N 100010 int n, m, p, erf;
int ans;
int a[N];
struct Que {
int l, r, opt;
}q[N];
int cnt[N*], lazy[N*];
#define ls(o) o << 1
#define rs(o) o << 1 | 1
inline void pushup(int o)
{
cnt[o] = cnt[ls(o)] + cnt[rs(o)];
} void Build(int l, int r, int o)
{
lazy[o] = -;
if (l == r)
{
cnt[o] = (a[l] >= erf);
lazy[o] = -;
return ;
}
int mid = l + r >> ;
Build(l, mid, ls(o));
Build(mid + , r, rs(o));
pushup(o);
}
//lazy : 1) -1 means none
// 2) 1 means change to 1
// 3) 0 means change to 0
inline void pushdown(int l, int r, int o)
{
if (lazy[o] == -) return ;
int mid = l + r >> ;
if (lazy[o] == ) {
cnt[ls(o)] = mid - l + ;
lazy[ls(o)] = ; cnt[rs(o)] = r - mid;
lazy[rs(o)] = ; lazy[o] = -;
} else {
cnt[ls(o)] = , lazy[ls(o)] = ;
cnt[rs(o)] = , lazy[rs(o)] = ;
lazy[o] = -;
}
} void change(int l, int r, int o, int ql, int qr, int c)
{
if (l >= ql and r <= qr) {
if (c) cnt[o] = r - l + , lazy[o] = ;
else cnt[o] = , lazy[o] = ;
return;
}
pushdown(l, r, o);
int mid = l + r >> ;
if (ql <= mid) change(l, mid, ls(o), ql, qr, c);
if (qr > mid) change(mid + , r, rs(o), ql, qr, c);
pushup(o);
} int query(int l, int r, int o, int ql, int qr)
{
if (l >= ql and r <= qr) return cnt[o];
pushdown(l, r, o);
int mid = l + r >> ;
int res = ;
if (mid >= ql) res += query(l, mid, ls(o), ql, qr);
if (mid < qr) res += query(mid + , r, rs(o), ql, qr);
return res;
} inline bool check(int mid)
{
erf = mid;
Build(, n, );
// printf("mid = %d\n", mid);
for (reg int i = ; i <= m ; i ++)
{
int L = q[i].l, R = q[i].r;
int c = query(, n, , L, R);
if (q[i].opt == ) { //升序
change(, n, , R - c + , R, );
change(, n, , L, R - c, );
} else {
change(, n, , L, L + c - , );
change(, n, , L + c, R, );
}
}
// printf("%d\n", query(1, n, 1, p, p));
return query(, n, , p, p);
} int main()
{
n = read(), m = read();
for (reg int i = ; i <= n ; i ++) a[i] = read();
for (reg int i = ; i <= m ; i ++) q[i].opt = read(), q[i].l = read(), q[i].r = read();
p = read();
int l = , r = n;
while (l <= r)
{
int mid = l + r >> ;
if (check(mid)) ans = mid, l = mid + ;
else r = mid - ;
}
printf("%d\n", ans);
return ;
}

[Luogu2824] [HEOI2016/TJOI2016]排序的更多相关文章

  1. 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告

    P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...

  2. [HEOI2016/TJOI2016]排序 线段树+二分

    [HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...

  3. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

  4. 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)

    2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...

  5. [HEOI2016&TJOI2016] 排序(线段树)

    4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2703  Solved: 1386[S ...

  6. [HEOI2016/TJOI2016]排序

    嘟嘟嘟 首先这题的暴力是十分好写的,而且据说能得不少分. 正解写起来不难,就是不太好想. 根据做题经验,我想到了给这个序列转化成01序列,但是接下来我就不会了.还是看了题解. 因为查询只有一个数,所以 ...

  7. 【线段树合并】【P2824】 [HEOI2016/TJOI2016]排序

    Description 给定一个长度为 \(n\) 的排列,有 \(m\) 次操作,每次选取一段局部进行升序或降序排序,问你一波操作后某个位置上的数字是几 Hint \(1~\leq~n,~m~\le ...

  8. 【[HEOI2016/TJOI2016]排序】

    巧妙思路题 有一个重要的思想就是把大于某一个数的数都变成\(1\),小于这个数的都变成\(0\),这个只有\(0\)和\(1\)的序列就很好处理了 由于我们只需要在最后求出一个位置上是什么数就可以了, ...

  9. BZOJ4552:[HEOI2016/TJOI2016]排序——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4552 https://www.luogu.org/problemnew/show/P2824 在2 ...

随机推荐

  1. http响应

    1.http响应 2.响应行常见状态码 200 :请求成功. 302 :请求重定向. 当访问网址A时,由于网址A服务器端的拦截器或者其他后端代码处理的原因,会被重定向到网址B. 304 :请求资源没有 ...

  2. Java第二次作业第三题

    四叶玫瑰线的图形设计:当用鼠标拖拽改变窗口大小时,四叶玫瑰线会重新绘制 package naizi; import java.awt.*; import java.awt.event.*; impor ...

  3. 三句话告诉你break、return、continue!

    break:终止循环执行循环体下面的代码 return:终止循环并且退出循环所在的方法 continue:终止当前循环,进行下一次循环

  4. Vue学习之不同组件之间的消息传递

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. mybatis无法给带有下划线属性赋值问题

    https://blog.csdn.net/qq_33768099/article/details/69569561

  6. JVM 内存区域大小参数设置

    JVM内存包括区域 Heap(堆区) New Generation(新生代) Eden 伊甸园 Survivor From Survivor To Old Generation(老年代) 方法区 Pe ...

  7. AJAX基础内容

    1.什么是ajax?为什么要使用ajax? ajax是Asynchronous JavaScript and XML ,也称为创建交互式网页应用开发技术. 2.为什么采用ajax 1)通过异步交互,提 ...

  8. Find the Multiple POJ-1426

    题目链接:Find the Multiple 题目大意 找出一个只由0和1组成的能整除n的数. 思路 所有由0和1组成的数可以看作是某个只由0.1组成的数a经过以下两种变化得到 1.a * 10 2. ...

  9. SPSS学习笔记参数检验—两配对样本t检验

    目的:检验两个有联系的正态总体的均值是否存在显著差异. 适用条件:有联系,正态总体,样本量要一样.一般可以分为一下四种: ①同一受试对象处理前后的对比:如对于糖尿病人,对同一组病人在使用新治疗方法前测 ...

  10. maven 打包构建相关命令

    1.命令 mvn clean package 依次执行clean.resources.compile.testResources.testCompile.test.jar(打包)等7个阶段. mvn ...