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. lintcode-162-矩阵归零

    162-矩阵归零 给定一个m×n矩阵,如果一个元素是0,则将其所在行和列全部元素变成0. 需要在原矩阵上完成操作. 样例 给出一个矩阵 [ [1, 2], [0, 3] ] 返回 [ [0, 2], ...

  2. noauth authentication required redis

    解决方案: 这是出现了认证的问题,是因为设置了认证密码. 127.0.0.1:6379> auth "yourpassword" 例如:

  3. iframe 随内容自适应高度

    兼容性好的 html代码: <iframe src="enterprise/enter_edit.aspx" id="mainframe" framebo ...

  4. iis7 appcmd命令

    iis中提供了appcmd命令 可以通过命令行来配置iis appcmd.exe 默认路径在 c:\windows\system32\inetsrv\下 若要回收应用程序池,请使用以下语法: appc ...

  5. 提升MyEclipse运行速度

    修改MyEclipse.ini文件中的,将-vmargs后面的参数修改为 -Xms256m -Xmx768m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:Max ...

  6. EL中定义函数

    1.在java类中要定义一个static函数 2配置:在WEB-INF/*.tld的配置文件 3在JSP页面上 4使用

  7. Java语言有哪些特点?

    1)简单 如果同学们学过C++语言,就会感觉Java眼熟,因为Java中许多基本语句的语法和C++是一样的,像常用的循环语句.控制语句等和C++几乎相同.需要注意的是,Java和C++时两种完全不同的 ...

  8. OpenCV2.3.1在Win7+VS2010下的配置过程

    1.  假定电脑上已经安装了VS2010程序,若没有,首先安装vs2010.下载OpenCV2.3.1,网址:http://sourceforge.net/projects/opencvlibrary ...

  9. HTML表单之input元素的23种type类型

    摘自:http://www.cnblogs.com/xiaohuochai/p/5179909.html 了解HTML表单之input元素的23种type类型 随着HTML5的出现,input元素新增 ...

  10. 生成模型(Generative Model)Vs 判别模型(Discriminative Model)

      概率图分为有向图(bayesian network)与无向图(markov random filed).在概率图上可以建立生成模型或判别模型.有向图多为生成模型,无向图多为判别模型. 判别模型(D ...