[Luogu2824] [HEOI2016/TJOI2016]排序
题目描述
在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位置上的数字。
输入输出样例
说明
河北省选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]排序的更多相关文章
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告
P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...
- [HEOI2016/TJOI2016]排序 线段树+二分
[HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...
- [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)
题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...
- 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)
2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...
- [HEOI2016&TJOI2016] 排序(线段树)
4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2703 Solved: 1386[S ...
- [HEOI2016/TJOI2016]排序
嘟嘟嘟 首先这题的暴力是十分好写的,而且据说能得不少分. 正解写起来不难,就是不太好想. 根据做题经验,我想到了给这个序列转化成01序列,但是接下来我就不会了.还是看了题解. 因为查询只有一个数,所以 ...
- 【线段树合并】【P2824】 [HEOI2016/TJOI2016]排序
Description 给定一个长度为 \(n\) 的排列,有 \(m\) 次操作,每次选取一段局部进行升序或降序排序,问你一波操作后某个位置上的数字是几 Hint \(1~\leq~n,~m~\le ...
- 【[HEOI2016/TJOI2016]排序】
巧妙思路题 有一个重要的思想就是把大于某一个数的数都变成\(1\),小于这个数的都变成\(0\),这个只有\(0\)和\(1\)的序列就很好处理了 由于我们只需要在最后求出一个位置上是什么数就可以了, ...
- BZOJ4552:[HEOI2016/TJOI2016]排序——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4552 https://www.luogu.org/problemnew/show/P2824 在2 ...
随机推荐
- rpm简单使用
rpm描述:利用源码包编译成rpm时,会去指定安装好这个包的位置本质:解压,然后拷贝到相关的目录,然后执行脚本 vstpd-3.0.2-9.el7.x86_64.rpm 包名 版本 release 架 ...
- SqlServer还原数据库时提示:异常终止,不能在此版本的SQL Server中启动,因为它包含分区函数
场景 在SqlServer Management中进行数据库还原时提示: 数据库不能在此版本的SQL Server中启动,因为它包含分区函数. 点击左下角的查看详细信息 实现 电脑上安装的是SQL S ...
- DNA sequence(映射+BFS)
Problem Description The twenty-first century is a biology-technology developing century. We know tha ...
- 一文搞懂 deconvolution、transposed convolution、sub-pixel or fractional convolution
目录 写在前面 什么是deconvolution convolution过程 transposed convolution过程 transposed convolution的计算 整除的情况 不整除的 ...
- 模板引擎Velocity学习系列-#set指令
#set指令 #set指令用于向一个变量或者对象赋值. 格式: #set($var = value) LHS是一个变量,不要使用特殊字符例如英文句号等,不能用大括号括起来.测试发现#set($user ...
- Spring——依赖注入(DI)详解
声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...
- Ext.js中树勾选的四种操作
最近在做控件优化的时候产品提了一个需求,对树的勾选要满足四种勾选方案: 1.点击一次根节点,当根节点和子节点均未选中的情况下,根节点和子节点全都选中. 2.第二次点击根节点,当根节点和部分或全部子节点 ...
- SSM框架中测试单元的使用,spring整合Junit
测试类中的问题和解决思路 3.1.1 问题 在测试类中,每个测试方法都有以下两行代码: ApplicationContext ac = new ClassPathXmlApplicatio ...
- C++ 函数模板用法
泛型编程概念:不考虑具体数据类型的编程方式: 函数模板: 1.提供一种特殊的函数可用不同类型进行调用: 2.与普通函数很相似,区别是类型可被参数化: template <typename T&g ...
- Android Studio [RecyclerView/瀑布流显示]
PuRecyclerViewActivity.java package com.xdw.a122.recyclerview; import android.support.v7.app.AppComp ...