题目描述

在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. Winform中将Bitmap对象通过picture显示图片

    场景 使用Zxing生成二维码时,返回的是Bitmap,现在要将其显示. Winform中显示照片的控件是pictureBox 实现 //二维码要存储的内容 string codeString = & ...

  2. 浅谈PHP反序列化漏洞原理

    序列化与反序列化 序列化用途:方便于对象在网络中的传输和存储 0x01 php反序列化漏洞 在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等. 常见的序列化格式: ...

  3. Elastic Stack 笔记(八)Elasticsearch5.6 Java API

    博客地址:http://www.moonxy.com 一.前言 Elasticsearch 底层依赖于 Lucene 库,而 Lucene 库完全是 Java 编写的,前面的文章都是发送的 RESTf ...

  4. C#加载前生成静态网页

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...

  5. python解释器安装和变量配置

    python解释器安装 第一步https://www.python.org/ 下载 python-3.6.6 和 python-2.7.16 俩个版本 Downloads 下 选windows版本 4 ...

  6. 通俗讲解 RESTful

    1 什么是 RESTful 百度一下 RESTful,查到的资料很多都讲得不清楚,看完了都不知道说的是啥,导致很多人对 RESTful 不甚了解.来看一下常见的解释: (1)神一样的描述REST 并不 ...

  7. Selenium+python操作id为动态变化的frame(iframe)

    先定位到一组frame:ele = dr.find_elements_by_tag_name('iframe')此时获得一组frame 再通过index取需要切进去的frame并取到该frame的id ...

  8. Android Studio [WebView]

    WebViewActivity.java package com.xdw.a122; import android.graphics.Bitmap; import android.support.v7 ...

  9. 使用Storm进行词频统计

    词频统计 1.需求:读取指定目录的数据,并且实现单词计数功能 2.实现方案: Spout用于读取指定文件夹(目录),读取文件,将文件的每一行发射到Bolt SplitBolt用于接收Spout发射过来 ...

  10. Spring boot 官网学习笔记 - Spring DevTools 介绍

    想要使用devtools支持,只需使用dependencies将模块依赖关系添加到你的构建中 运行打包的应用程序时,开发人员工具会自动禁用.如果你通过 java -jar或者其他特殊的类加载器进行启动 ...