Description

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

Input

输入数据的第一行为两个整数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
 

Output

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

Sample Input

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

Sample Output

5
————————————————————————————————
二分p位置的值,把大于mid的数改为1,小于等于mid的数改为0,
变成01串后就可以用线段树实现排序了,像降序升序什么的操作就把1和0各堆到一边就可以辣
排序后如果p的位置上的数为0,说明答案比mid小,如果为1,说明答案比mid大。
至于为什么可以用二分呢
你想如果p位置上是1,说明mid较小,v[p]>mid,所以把v[p]给标记成了1。
如果p位置上是0,就是把v[p]<=mid,所以把v[p]标记成了0,
但是这样还有一些大于v[p]的位置也是0,所以继续往小的地方逼近答案。
满足单调所以就可以这么写辣
#include<cstdio>
#include<cstring>
#include<algorithm>
const int M=5e5+;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int p,n,m,v[M];
int lx[M],rx[M],op[M];
int L,R,mx;
struct pos{int s,h[];}tr[M];
void up(int x){tr[x].s=tr[x<<].s+tr[x<<^].s;}
void down(int x,int l,int r){
if(l==r) return ;
int ls=x<<,rs=x<<^,mid=(l+r)>>;
if(tr[x].h[]){
tr[x].h[]=;
tr[ls].h[]=tr[rs].h[]=;
tr[ls].s=tr[rs].s=;
tr[ls].h[]=tr[rs].h[]=;
}
else if(tr[x].h[]){
tr[x].h[]=; tr[ls].h[]=tr[rs].h[]=;
tr[ls].s=mid-l+; tr[rs].s=r-mid;
tr[ls].h[]=tr[rs].h[]=;
}
}
void build(int x,int l,int r){
tr[x].h[]=tr[x].h[]=;
if(l==r){
tr[x].s=(v[l]>mx);
return ;
}
int mid=(l+r)>>;
build(x<<,l,mid);
build(x<<^,mid+,r);
up(x);
}
void modify(int x,int l,int r,int v){
if(L<=l&&r<=R){
tr[x].h[v]=;
tr[x].h[v^]=;
tr[x].s=(r-l+)*v;
return ;
}
down(x,l,r);
int mid=(l+r)>>;
if(L<=mid) modify(x<<,l,mid,v);
if(R>mid) modify(x<<^,mid+,r,v);
up(x);
}
int query(int x,int l,int r){
if(L<=l&&r<=R) return tr[x].s;
down(x,l,r);
int mid=(l+r)>>,sum=;
if(L<=mid) sum+=query(x<<,l,mid);
if(R>mid) sum+=query(x<<^,mid+,r);
return sum;
}
bool check(int k){
mx=k; build(,,n);
for(int i=;i<=m;i++){
L=lx[i]; R=rx[i];
int ly=query(,,n);
if(op[i]){
if(ly) L=lx[i],R=lx[i]+ly-,modify(,,n,);
if(lx[i]+ly<=rx[i]) L=lx[i]+ly,R=rx[i],modify(,,n,);
}
else{
if(lx[i]<=rx[i]-ly) L=lx[i],R=rx[i]-ly,modify(,,n,);
if(ly) L=rx[i]-ly+,R=rx[i],modify(,,n,);
}
}
L=R=p;
return !query(,,n);
}
int main(){
n=read(); m=read();
for(int i=;i<=n;i++) v[i]=read();
for(int i=;i<=m;i++) op[i]=read(),lx[i]=read(),rx[i]=read();
p=read();
int l=,r=n;
while(l<r){
int mid=(l+r)>>;
if(check(mid)) r=mid;
else l=mid+;
}printf("%d\n",l);
return ;
}

bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树的更多相关文章

  1. 【BZOJ4552】[Tjoi2016&Heoi2016]排序 二分+线段树

    [BZOJ4552][Tjoi2016&Heoi2016]排序 Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ...

  2. bzoj 4552 [Tjoi2016&Heoi2016]排序 (二分答案 线段树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意: 给你一个1-n的全排列,m次操作,操作由两种:1.将[l,r]升序排序,2 ...

  3. BZOJ 4552 [Tjoi2016&Heoi2016]排序 | 二分答案 线段树

    题目链接 题面 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...

  4. [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树

    Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...

  5. bzoj 4552 [Tjoi2016&Heoi2016]排序——二分答案

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案,把 >= mid 的设成1.< mid 的设成0,之后排序就变成 ...

  6. BZOJ 4552: [Tjoi2016&Heoi2016]排序

    4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 579  Solved: 322[Sub ...

  7. BZOJ 4552: [Tjoi2016&Heoi2016]排序 线段树 二分

    目录 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 update 10.6 此代码是个假代码,只能糊弄luogu,以后再改,路过大佬也可以帮一下辣 /* //fang zhi ...

  8. bzoj 4552: [Tjoi2016&Heoi2016]排序【二分+线段树】

    二分值mid,然后把>=mid的赋值为1,其他赋值为0,每次排序就是算出区间内01的个数,然后分别把0和1放到连续的一段内,这些都可以用线段树来维护 二分的判断条件是操作完之后q位置上是否为1 ...

  9. BZOJ 4552 [Tjoi2016&Heoi2016]排序 ——线段树 二分答案

    听说是BC原题. 好题,二分答案变成01序列,就可以方便的用线段树维护了. 然后就是区间查询和覆盖了. #include <map> #include <cmath> #inc ...

随机推荐

  1. servlet转发和重定向

    1 转发 RequestDispatcher getRequestDispatcher(java.lang.String path) 1)地址栏不会改变 2)转发只能转发到当前web应用内的资源 3) ...

  2. VS2012或VS2010 工具栏中无法显示DevExpress控件

    进入命令提示符 跳转到Dev控件安装目录,如[目录D:\Program Files (x86)\DevExpress\DXperience 12.2\Tools]下, 然后执行命令: ToolboxC ...

  3. centos7 安装 httpd并打开测试页

    systemctl start firewalld.service#启动firewallsystemctl stop firewalld.service#停止firewallsystemctl dis ...

  4. shell基础练习题讲解

    1037774765 克隆 1.创建一个用户redhat,其ID号为1001,基本组为like(组ID为2002),附近租为linux. groupadd -g 2002 likegroupadd l ...

  5. matlab中滤波函数

    matlab自带滤波器函数小结(图像处理)   1 线性平滑滤波器 用MATLAB实现领域平均法抑制噪声程序: I=imread(' c4.jpg '); subplot(231) imshow(I) ...

  6. volatile并不能保证数据同步、只能保证读取到最新主内存数据

    在 java 垃圾回收整理一文中,描述了jvm运行时刻内存的分配.其中有一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈, 线程栈保存了线程运行时候变量值信息.当线程访问某一个对象时候值的 ...

  7. jQuery的动画与特效

    显示与隐藏 show() 和 hide() 方法 动画效果的show() 和 hide() show(speed,[]callback) hide(speed,[]callback) speed:表示 ...

  8. Swift学习与复习

    swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...

  9. BZOJ 1022 小约翰的游戏(anti-sg)

    这是个anti-sg问题,套用sj定理即可解. SJ定理 对于任意一个Anti-SG游戏,如果定义所有子游戏的SG值为0时游戏结束,先手必胜的条件: 1.游戏的SG值为0且所有子游戏SG值均不超过1. ...

  10. Javascript-基础2

    1. Javascript 字符串里面的方法: obj.length 长度 obj.trim() 移除空白 obj.trimLeft() obj.trimRight) obj.charAt(n) 返回 ...