洛谷 2824 [HEOI2016/TJOI2016]排序

【题意概述】
对一个1到n的排列做m次区间排序,最后询问位置q上面的数。
【题解】
区间排序的效率是nlogn,所以暴力做的话效率是mnlogn,显然达不到要求。
我们考虑二分答案。如果某个位置的数比mid小,就设为0,如果么某个位置的数大于等于mid,就设为1. check的时候我们只需对01序列排序就好了,这个可以用线段树做到logn.
如果排序后位置q的数为1,那么就表示原来这里的数大于等于mid,所以我们要挪动l,否则挪动r.
总的时间复杂度为m*logn*logn
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define rg register
#define N 30010
#define ls (u<<1)
#define rs (u<<1|1)
#define len(x) (a[x].r-a[x].l+1)
using namespace std;
int n,m,v[N],l,r,mid,pos;
struct tree{
int l,r,c0,c1,num; bool same;
}a[N<<];
struct opt{
int l,r,type;
}b[N];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
void build(int u,int l,int r){
a[u].l=l; a[u].r=r; a[u].same=; a[u].c0=a[u].c1=;
if(l<r){
int mid=(l+r)>>;
build(ls,l,mid); build(rs,mid+,r);
a[u].c0=a[ls].c0+a[rs].c0; a[u].c1=a[ls].c1+a[rs].c1;
}
else{
if(v[l]>=mid) a[u].c1=,a[u].c0=;
else a[u].c0=,a[u].c1=;
}
}
inline void pushdown(int u){
a[u].same=; a[ls].same=a[rs].same=;
a[ls].num=a[rs].num=a[u].num;
if(!a[u].num) a[ls].c0=len(ls),a[ls].c1=,a[rs].c0=len(rs),a[rs].c1=;
else a[ls].c0=,a[ls].c1=len(ls),a[rs].c0=,a[rs].c1=len(rs);
}
void update(int u,int l,int r,int num){
if(l<=a[u].l&&a[u].r<=r){
a[u].same=; a[u].num=num;
if(num==) a[u].c1=len(u),a[u].c0=;
else a[u].c0=len(u),a[u].c1=;
return;
}
if(a[u].same) pushdown(u);
int mid=(a[u].l+a[u].r)>>;
if(l<=mid) update(ls,l,r,num);
if(r>mid) update(rs,l,r,num);
a[u].c0=a[ls].c0+a[rs].c0;
a[u].c1=a[ls].c1+a[rs].c1;
}
int query0(int u,int l,int r){
if(l<=a[u].l&&a[u].r<=r) return a[u].c0;
if(a[u].same) pushdown(u);
int mid=(a[u].l+a[u].r)>>,ret=;
if(l<=mid) ret=query0(ls,l,r);
if(r>mid) ret+=query0(rs,l,r);
return ret;
}
int query1(int u,int l,int r){
if(l<=a[u].l&&a[u].r<=r) return a[u].c1;
if(a[u].same) pushdown(u);
int mid=(a[u].l+a[u].r)>>,ret=;
if(l<=mid) ret=query1(ls,l,r);
if(r>mid) ret+=query1(rs,l,r);
return ret;
}
inline bool check(){
build(,,n); int r0=,r1=;
for(rg int i=;i<=m;i++){
r0=query0(,b[i].l,b[i].r); r1=query1(,b[i].l,b[i].r);
if(b[i].type==) update(,b[i].l,b[i].l+r0-,),update(,b[i].l+r0,b[i].r,);
else update(,b[i].l,b[i].l+r1-,),update(,b[i].l+r1,b[i].r,);
}
r0=query0(,pos,pos); r1=query1(,pos,pos);
return r1>;
}
int main(){
n=read(); m=read();
for(rg int i=;i<=n;i++) v[i]=read();
for(rg int i=;i<=m;i++) b[i].type=read(),b[i].l=read(),b[i].r=read();
pos=read();
l=,r=n+;
while(l+<r){
mid=(l+r)>>;
if(check()) l=mid; else r=mid;
}
printf("%d\n",l);
}
洛谷 2824 [HEOI2016/TJOI2016]排序的更多相关文章
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告
P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...
- [洛谷P2824][HEOI2016/TJOI2016]排序
题目大意:一个全排列,两种操作: 1. $0\;l\;r:$把$[l,r]$升序排序2. $1\;l\;r:$把$[l,r]$降序排序 最后询问第$k$位是什么 题解:二分答案,把比这个数大的赋成$1 ...
- 洛谷P2824 [HEOI2016/TJOI2016]排序(线段树)
传送门 这题的思路好清奇 因为只有一次查询,我们考虑二分这个值为多少 将原序列转化为一个$01$序列,如果原序列上的值大于$mid$则为$1$否则为$0$ 那么排序就可以用线段树优化,设该区间内$1$ ...
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)
(另外:题解中有一种思路很高妙而且看上去可以适用一些其他情况的离线方法) 线段树合并&复杂度的简单说明:https://blog.csdn.net/zawedx/article/details ...
- 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分
正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP
洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...
- BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...
- 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告
P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告
P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...
随机推荐
- NTFS中的ADS的一些问题
有关ADS的简单说明请看http://www.xfocus.net/articles/200212/466.html 可以看到ADS在很久以前就被一些安全人员所关注,并且也提出了一些经典的利用,比如隐 ...
- E20171226-hm
stack n.栈 heap n.堆 backtracking 回溯法,後戻り storage n. 贮存; 贮藏; 储藏处,仓库; 贮存器,蓄电(瓶); ストレージ
- Linux系统基本信息查看
Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然. 1.# uname -a (Linux查看版本当前操作系统内核信息) 2.# ...
- 1642: [Usaco2007 Nov]Milking Time 挤奶时间(dp)
1642: [Usaco2007 Nov]Milking Time 挤奶时间 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 935 Solved: 55 ...
- 基于.Net Core的API框架的搭建(2)
4.加入数据库支持 下面我们为项目加入数据库支持,修改appsettings.json: 然后我们要生成实体类,打开VS工具->NuGet包管理器->程序包管理器控制台: 输入命令: Sc ...
- Js 使用小技巧总结(1)
1.Js 的时间控制,小于初始时间,大于截止时间 <script type="text/javascript"> window.onload = Game ...
- 笔记本 windows 10 安装
开机按快捷键是F12,选择从usb启动.秋叶系统 很好用,推荐使用. 联想笔记本u深度一键u盘启动BIOS设置教程:准备工作:制作好u深度u盘启动盘http://rj.baidu.com/soft/d ...
- 290 Word Pattern 单词模式
给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循这种模式.这里的 遵循 指完全匹配,例如在pattern里的每个字母和字符串 str 中的每个非空单词存在双向单映射关系 ...
- Hadoop Hive概念学习系列之hive的索引及案例(八)
hive里的索引是什么? 索引是标准的数据库技术,hive 0.7版本之后支持索引.Hive提供有限的索引功能,这不像传统的关系型数据库那样有“键(key)”的概念,用户可以在某些列上创建索引来加速某 ...
- Java多线程——线程之间的同步
Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...