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. DAY3敏捷冲刺

    站立式会议 工作安排 (1)服务器配置 (2)数据库配置 燃尽图 燃尽图有误,已重新修改,先贴卡片的界面,后面补修改后燃尽图 代码提交记录

  2. Alpha 冲刺4

    队名:日不落战队 安琪(队长) 今天完成的任务 组织第四次站立式会议. 完成40%草稿箱前端界面. 明天的计划 剩下的60%草稿箱前端界面. 如果还有时间,尝试去调用数据. 还剩下的任务 回收站前端界 ...

  3. (五)final修饰符

    final修饰变量 final修饰符一般用于基本数据类型(int,float)或者不可变对象(String).这时候可以看作常量变量. 但是当final作用于可变数据类型时(数组,一般对象),仅仅表示 ...

  4. (转)centos6.5下Zabbix系列之Zabbix安装搭建及汉化

    最近在研究zabbix,在整理完成之后就有了写一下总结博客的想法,在我研究zabbix的时候给我很大帮助的是it你好,博客地址 http://itnihao.blog.51cto.com/他做的zab ...

  5. Linux中实现在系统启动时自动加载模块

    下面是以前学习Linux时写的,后来仔细研究rc.sysinit后发现,只需要修改下列地方就可以了,不必这么麻烦的: rc.sysinit中有这样的一段代码: # Load other user-de ...

  6. 在a标签的href用户#name 的可以实现页面 上下跳转

  7. iOS-开发中的时间处理

    做App避免不了要和时间打交道,关于时间的处理,里面有不少门道,远不是一行API调用,获取当前系统时间这么简单.我们需要了解与时间相关的各种API之间的差别,再因场景而异去设计相应的机制. 时间的形式 ...

  8. 转:Conjugate prior-共轭先验的解释

    Conjugate prior-共轭先验的解释    原文:http://blog.csdn.net/polly_yang/article/details/8250161 一 问题来源: 看PRML第 ...

  9. [洛谷P3793]由乃救爷爷

    题目大意:有$n(n\leqslant2\times10^7)$个数,$m(m\leqslant2\times10^7)$个询问,每次询问问区间$[l,r]$中的最大值.保证数据随机 题解:分块,处理 ...

  10. [CTSC2014]企鹅QQ hash

    ~~~题面~~~ 题解: 通过观察可以发现,其实题目就是要求长度相等的字符串中有且只有1位字符不同的 ”字符串对“ 有多少. 因为数据范围不大, 所以考虑一种暴力至极的方法. 我们枚举是哪一位不同,然 ...