P2824 [HEOI2016/TJOI2016] 排序(线段树)(内附封面)

news2025/1/18 18:46:57

[HEOI2016/TJOI2016] 排序

题目描述

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

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

  • 0 l r 表示将区间 [ l , r ] [l,r] [l,r] 的数字升序排序
  • 1 l r 表示将区间 [ l , r ] [l,r] [l,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 1 1 n n n 的一个排列。

接下来输入 m m m 行,每一行有三个整数 op , l , r \text{op},l,r op,l,r op \text{op} op 0 0 0 代表升序排序, op \text{op} op 1 1 1 代表降序排序, l , r l,r l,r 表示排序的区间。

最后输入一个整数 q q q,表示排序完之后询问的位置

输出格式

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

样例 #1

样例输入 #1

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

样例输出 #1

5

提示

河北省选2016第一天第二题。

对于 30 % 30\% 30% 的数据, n , m ≤ 1000 n,m\leq 1000 n,m1000

对于 100 % 100\% 100% 的数据, n , m ≤ 1 0 5 n,m\leq 10^5 n,m105 1 ≤ q ≤ n 1\leq q\leq n 1qn

线段树真的太好用好调了,所以我什么时候能去给线段树献花圈顺便在坟头蹦迪

大致思路

  • 我们最终只需要一次访问,经过二分答案得到mid,那么数组内只会有两种数,大于等于mid的和小于mid的数。
  • 对于大于等于mid的数我们标为1,小于mid的我们标为0,每次操作也就变成了给01序列排序
  • 整个题也就变成了两个部分,如何维护用线段树维护这个01序列及二分答案的具体实现

线段树维护01序列排序

首先我们要求出当前区间有几个1,设cnt

  • 升序:将 [ l , r − c n t ] 赋值 0 [l,r-cnt]赋值0 [l,rcnt]赋值0, [ r − c n t + 1 , r ] 赋值 1 [r-cnt+1,r]赋值1 [rcnt+1,r]赋值1
  • 降序:将 [ l , l + c n t − 1 ] 赋值 1 [l,l+cnt-1]赋值1 [l,l+cnt1]赋值1, [ r , r − c n t ] 赋值 0 [r,r-cnt]赋值0 [r,rcnt]赋值0
    举个例子,对于序列
    0   0   1   0   1   0 0\space0\space1\space 0\space 1\space 0 0 0 1 0 1 0
    其中 c n t = 2 cnt=2 cnt=2
    对[2,4]升序排序: 0   0   0   1   1   0 0\space0\space0\space 1\space 1\space0 0 0 0 1 1 0
    对[2,4]降序排序: 0   1   1   0   0   0 0\space1\space1\space 0\space 0\space0 0 1 1 0 0 0

这样,排序问题就被转化为了区间修改,区间查询,单点查询问题。

bool check(int md){
	build(1,1,n,md);
	for(int i=1;i<=m;i++){
		int cnt=query(1,1,n,l[i],r[i]);
		if(op[i]==0){
			update(1,1,n,l[i],r[i]-cnt,0);
			update(1,1,n,r[i]-cnt+1,r[i],1);
		}
		else if(op[i]==1){
			update(1,1,n,l[i]+cnt,r[i],0);
			update(1,1,n,l[i],l[i]+cnt-1,1);
		}
	}
	return query_point(1,1,n,q);
}
	while(ll<=rr){
		int mmid=(ll+rr)>>1;
		if(check(mmid)){
			ll=mmid+1;
		}
		else {
			rr=mmid-1;
		}
	}
	cout<<rr<<endl;

奇妙の二分答案

经过元素与mid比较,建树,操作后再次查询q,若q为1,说明当前数可行,更新L为mid+1,反正更新R为mid-1

bool check(int md){
	build(1,1,n,md);
	for(int i=1;i<=m;i++){
		int cnt=query(1,1,n,l[i],r[i]);
		if(op[i]==0){
			update(1,1,n,l[i],r[i]-cnt,0);
			update(1,1,n,r[i]-cnt+1,r[i],1);
		}
		else if(op[i]==1){
			update(1,1,n,l[i]+cnt,r[i],0);
			update(1,1,n,l[i],l[i]+cnt-1,1);
		}
	}
	return query_point(1,1,n,q);
}

本题的思想非常巧妙,值得借鉴!

AC CODE

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+888;
int n,m,q,l[N],r[N],op[N];
int sm[N<<2],tag[N<<2],a[N];
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
#define int long long int 
void pushup(int x){
	sm[x]=sm[lc(x)]+sm[rc(x)];
}
void build(int x,int l,int r,int midd){
	tag[x]=0;
	if(l==r){
		if(a[l]<midd){
			sm[x]=0;
		}
		else sm[x]=1;
		return;
	}
	int mid=(l+r)>>1;
	build(lc(x),l,mid,midd);
	build(rc(x),mid+1,r,midd);
	pushup(x);
}
void cover(int x,int l,int r,int ad){	
	sm[x]+=(r-l+1)*ad;
	if(ad==1) tag[x]=ad;
	else tag[x]=-1;
}
void pushdown(int x,int l,int r){
	if(!tag[x])return;
	int mid=(l+r)>>1;
//	cover(lc(x),l,mid,tag[x]);
//	cover(rc(x),mid+1,r,tag[x]);
	tag[lc(x)]=tag[rc(x)]=tag[x];
	if(tag[x]==1){
		sm[lc(x)]=mid-l+1;
		sm[rc(x)]=r-mid;
	}
	else {
		sm[lc(x)]=sm[rc(x)]=0;	
	}
	tag[x]=0;
}
void update(int x,int l,int r,int L,int R,int ad){
	if(l>R||r<L)return;
	if(l>=L&&R>=r){
		//cover(x,l,r,ad);
		sm[x]=(r-l+1)*ad;
		if(ad==1){
			tag[x]=1;
		}
		else tag[x]=-1;
		return;
	}
	pushdown(x,l,r);
	int mid=(l+r)>>1;
	update(lc(x),l,mid,L,R,ad);
	update(rc(x),mid+1,r,L,R,ad);
	pushup(x);
}
int query(int x,int l,int r,int L,int R){
	if(l>R||r<L)return 0;
	if(l>=L&&R>=r){
		return sm[x];
	}
	int mid=(l+r)>>1;
	pushdown(x,l,r);
	return query(lc(x),l,mid,L,R)+query(rc(x),mid+1,r,L,R);
}
int query_point(int x,int l,int r,int xy){
//	if(l>xy||r<xy)return 0;
	if(l==r&&l==xy){
		return sm[x];
	}
	int mid=(l+r)>>1;
	pushdown(x,l,r);
	if(xy<=mid) return query_point(lc(x),l,mid,xy);
	else return query_point(rc(x),mid+1,r,xy);
}
bool check(int md){
	build(1,1,n,md);
	for(int i=1;i<=m;i++){
		int cnt=query(1,1,n,l[i],r[i]);
		if(op[i]==0){
			update(1,1,n,l[i],r[i]-cnt,0);
			update(1,1,n,r[i]-cnt+1,r[i],1);
		}
		else if(op[i]==1){
			update(1,1,n,l[i]+cnt,r[i],0);
			update(1,1,n,l[i],l[i]+cnt-1,1);
		}
	}
	return query_point(1,1,n,q);
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=m;i++){
		cin>>op[i]>>l[i]>>r[i];
	}
	cin>>q;
	int ll=0,rr=1999990;
	while(ll<=rr){
		int mmid=(ll+rr)>>1;
		if(check(mmid)){
			ll=mmid+1;
		}
		else {
			rr=mmid-1;
		}
	}![请添加图片描述](https://img-blog.csdnimg.cn/95443962d73e4da588fa06edf7ca3579.png)

	cout<<rr<<endl;
	return 0;
}

完结撒花~

附封面(古河渚)

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/829208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于单测技术选型,聊聊我的思考

对于单测来说&#xff0c;目前常用的单测框架有&#xff1a; JUnitMockitoSpockPowerMockJMockitTestableMock 其中 JUnit 不支持 Mock&#xff0c;因此基本不会只用 JUnit&#xff0c;而是结合其他有 Mock 功能的框架一起使用。从知名度及使用率来说&#xff0c;Mockito 和 …

【基于HBase和ElasticSearch构建大数据实时检索项目】

基于HBase和ElasticSearch构建大数据实时检索项目 一、项目说明二、环境搭建三、编写程序四、测试流程 一、项目说明 利用HBase存储海量数据&#xff0c;解决海量数据存储和实时更新查询的问题&#xff1b;利用ElasticSearch作为HBase索引&#xff0c;加快大数据集中实时查询数…

干就完了

&#xff08;1&#xff09; ENIAC诞生于1946年。但安达信在1954年就拿计算机给通用电气公司算薪&#xff0c;这算计算机最早在工商业界的应用。 其实算薪这个事吧&#xff0c;严格意义来说是人力服务的BPO&#xff0c;只不过为了让这个算薪BPO项目更高效率更高质量更低成本地完…

无人机巢的作用及应用领域解析

无人机巢作为无人机领域的创新设备&#xff0c;不仅可以实现无人机的自主充电和电池交换&#xff0c;还为无人机提供安全便捷的存放空间。为了帮助大家更好地了解无人机巢&#xff0c;本文将着重解析无人机巢的作用和应用领域。 一、无人机巢的作用 无人机巢作为无人机技术的重…

模型优化调参方法介绍(Python代码)

模型算法在机器学习和深度学习中都发挥着自己的作用&#xff0c;但往往训练出来的模型效果不佳或稳定性不强&#xff0c;就需要对模型进行调优。一般来说&#xff0c;会从以下几个角度来优化模型。 1.优化数据维度 在需要对原始需求进行理解、准确定义好坏样本的前提下&#…

MySQL第六七弹,自连接等复杂查询,索引部分知识

一、&#x1f49b; 自连接&#xff1a;自己和自己笛卡尔积&#xff08;奇淫巧技&#xff0c;特殊场景很牛逼&#xff09; SQL&#xff1a;编写条件都是列和列之间的比较&#xff0c;但是SQL无法进行&#xff0c;行与行之间的比较。 如&#xff1a;显示所有java比计算机原理高的…

中电金信杜啸争:逐“数”兴业,智胜未来

在数字化转型大潮中&#xff0c;数据要素市场未来如何发展&#xff1f;作为天然具有大量数据应用场景和需求的金融行业&#xff0c;能否逐“数”兴业&#xff0c;实现“换道超车”&#xff1f; 本期分享由中电金信商业分析事业部总经理&#xff0c;中电金信数据研发委员会主席…

Cpp8 — 二叉搜索树

二叉搜索树&#xff08;搜索二叉树、二叉排序树&#xff09; 二叉搜索树又称二叉排序树&#xff0c;它要么是一棵空树&#xff0c;要么是具有以下性质的二叉树&#xff1a; 1.若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 2.若它的右子树不为空&…

刷题笔记 day5

力扣 202 快乐数 首先来分析什么样的数是快乐数&#xff0c; 解题思路&#xff1a; 1&#xff09;定义快慢指针 &#xff1b; 2&#xff09;快指针走两步&#xff0c;慢指针走一步 &#xff1b;3&#xff09;两个指针相遇时判断相遇的数值是否为1。 怎样处理 取各分位数的平…

ReentrantLock源码解析和AQS常见问题分析

ReentrantLock和AQS常见问题分析 一、前言 本文利用ReentrantLock作为阅读AQS的切入口&#xff0c;通过问答的方式让大家更好的去理解今天要掌握的点&#xff0c;也欢迎大家说说自己的答案。 二、本文大纲 脑图是个很好的辅助记忆工具&#xff0c;也能提高自己的逻辑思维能…

计算机中数据的表示

计算机数据表示 送入计算机的数字&#xff0c;字母&#xff0c;符号等信息必须转换成0、 1组合的数据形式才能被计算机识别。 能够进行算术运算得到明确数值概念的信息成为计算机数值数据&#xff0c;其余的信息成为非数值数据。 从计算机本质的角度而言啊&#xff0c;它所处理…

《零基础入门学习Python》第077讲:Tkinter 模块:标准对话框

Tkinter 为了提供了三种标准对话框模块&#xff0c;它们分别是&#xff1a; messageboxfiledialogcolorchooser 注&#xff1a;这三个模块原来是独立的&#xff0c;分别是 tkMessageBox、tkFileDialog 和 tkColorChooser&#xff0c;需要导入才能使用。在 Python3 之后&#…

http和https的区别?(网络通讯)

HTTP&#xff1a; 超文本传输协议&#xff08;HTTP&#xff0c;HyperText Transfer Protocol&#xff09;是互联网上应用最为广泛的一种 网络协议 HTTPS&#xff1a; 是以安全为目标的 HTTP 通道&#xff0c;是 HTTP 的安全版。HTTPS 的安全基础是 SSL。 两者区别: 1、HTTPS …

Vue3_02 创建Vue3.0工程

1.使用 vue-cli 创建 ## 查看 vue/cli 版本&#xff0c;确保 vue/cli 版本在4.5.0以上 vue -V 或 vue --version## 安装或升级你的 vue/cli npm install -g vue/cli## 创建 vue create vue_test## 启动 cd vue-test npm run serve 2.使用 vite 创建 什么是vite?——新一代…

Golang之路---03 面向对象——接口与多态

接口与多态 何为接口 在面向对象的领域里&#xff0c;接口一般这样定义&#xff1a;接口定义一个对象的行为。接口只指定了对象应该做什么&#xff0c;至于如何实现这个行为&#xff08;即实现细节&#xff09;&#xff0c;则由对象本身去确定。   在 Go 语言中&#xff0c;…

24考研数据结构-二叉树的遍历

目录 5.3二叉树的遍历和线索二叉树数据结构&#xff1a;树的遍历前序遍历中序遍历后序遍历层次遍历遍历方法的选择结论 树的遍历应用5.3.1二叉树的遍历1. 先序遍历&#xff08;根左右 NLR&#xff09;2. 中序遍历&#xff08;左根右 LNR&#xff09;3. 后续遍历&#xff08;左右…

基于Jenkins+Python+Ubuntu+Docker的接口/UI自动化测试环境部署详细过程

基于JenkinsPythonUbuntuDocker的接口/UI自动化测试环境部署详细过程 1 Jenkins是什么&#xff1f;2 Jenkins目标是什么&#xff1f;3 什么是CI/CD?3.1 CI持续集成3.2 CD持续部署3.3 CD持续交付 4 Ubuntu环境4.1 环境需求4.2 实现思路 5 Ubuntu下安装Docker6 安装Jenkins6.1 拉…

电力巡检无人机助力迎峰度夏,保障夏季电力供应

夏季是电力需求量较高的时期&#xff0c;随着高温天气的来临&#xff0c;风扇、空调和冰箱等电器的使用量也大大增加&#xff0c;从而迎来夏季用电高峰期&#xff0c;电网用电负荷不断攀升。为了保障夏季电网供电稳定&#xff0c;供电公司会加强对电力设施设备的巡检&#xff0…

新抗原预测的计算工作流程

参考文献&#xff1a;Xie N, Shen G, Gao W, Huang Z, Huang C, Fu L. Neoantigens: promising targets for cancer therapy. Signal Transduct Target Ther. 2023 Jan 6;8(1):9. doi: 10.1038/s41392-022-01270-x. PMID: 36604431; PMCID: PMC9816309. 文章目录 *新抗原预测的…

【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio快速构建React完成点餐H5页面还原

【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio快速构建React完成点餐H5页面还原 一、前言二、Cloud Studio 简介1.Cloud Studio 是什么2.Cloud Studio 的优点 三、Cloud Studio 登录注册四、Cloud Studio 的初体验五、使用 Cloud Studio 开发一个简版的点餐系统1.安装 a…