Description

给出一个$1$到$n$的全排列,现在对这个全排列序列进行$m$次局部排序,排序分为$2$种:

$1.(0,l,r)$表示将区间$[l,r]$的数字升序排序;

$2.(1,l,r)$表示将区间$[l,r]$的数字降序排序.

最后询问第$q$位置上的数字.

Input

第$1$行为两个整数$n$和$m$.$n$表示序列的长度,$m$表示局部排序的次数.

第$2$行为$n$个整数,表示$1$到$n$的一个全排列.

接下来输入$m$行,每$1$行有$3$个整数$op,l,r$.

$op$为$0$代表升序排序,$op$为$1$代表降序排序;$l,r$表示排序的区间.

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

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

HINT

$1\;\leq\;n,m\;\leq\;10^5,1\;\leq\;q\;\leq\;n.$

Solution

二分答案$ans$.

把$\;\leq\;ans$的位置标为$1$,其余标为$0$.

线段树维护排序操作,最后判断位置$q$上是否为$0$.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100005
#define M 300005
using namespace std;
struct linetree{
int l,r,t,op;
}lt[M];
struct quest{
int op,l,r;
}b[N];
int a[N],n,m,q,t,l,r,mid;
inline void build(int u,int l,int r,int k){
lt[u].l=l;lt[u].r=r;lt[u].op=0;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
build(lef,l,mid,k);build(rig,mid+1,r,k);
lt[u].t=lt[lef].t+lt[rig].t;
}
else if(a[lt[u].l]>=k) lt[u].t=0;
else lt[u].t=1;
}
inline void cover(int u,int i){
if(lt[u].l>=b[i].l&&lt[u].r<=b[i].r){
if(!b[i].op){
lt[u].op=-1;
if(lt[u].l-b[i].l+1<=t){
lt[u].t=min(t-(lt[u].l-b[i].l),lt[u].r-lt[u].l+1);
}
else lt[u].t=0;
}
else{
lt[u].op=1;
if(b[i].r-lt[u].r+1<=t){
lt[u].t=min(t-(b[i].r-lt[u].r),lt[u].r-lt[u].l+1);
}
else lt[u].t=0;
}
}
else if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].op>0)/*降序*/{
lt[u].op=0;lt[lef].op=lt[rig].op=1;
lt[rig].t=min(lt[u].t,lt[rig].r-lt[rig].l+1);
lt[lef].t=lt[u].t-lt[rig].t;
}
else if(lt[u].op<0)/*升序*/{
lt[u].op=0;lt[lef].op=lt[rig].op=-1;
lt[lef].t=min(lt[u].t,lt[lef].r-lt[lef].l+1);
lt[rig].t=lt[u].t-lt[lef].t;
}
if(b[i].l<=mid) cover(lef,i);
if(b[i].r>mid) cover(rig,i);
lt[u].t=lt[lef].t+lt[rig].t;
}
}
inline int ask(int u,int l,int r){
if(lt[u].l>=l&&lt[u].r<=r)
return lt[u].t;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1,ret=0;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].op>0)/*降序*/{
lt[u].op=0;lt[lef].op=lt[rig].op=1;
lt[rig].t=min(lt[u].t,lt[rig].r-lt[rig].l+1);
lt[lef].t=lt[u].t-lt[rig].t;
}
else if(lt[u].op<0)/*升序*/{
lt[u].op=0;lt[lef].op=lt[rig].op=-1;
lt[lef].t=min(lt[u].t,lt[lef].r-lt[lef].l+1);
lt[rig].t=lt[u].t-lt[lef].t;
}
if(l<=mid) ret+=ask(lef,l,r);
if(r>mid) ret+=ask(rig,l,r);
return ret;
}
}
inline bool chk(int k){
build(1,1,n,k);
for(int i=1;i<=m;++i){
t=ask(1,b[i].l,b[i].r);cover(1,i);
}
return !ask(1,q,q);
}
inline void init(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=m;++i)
scanf("%d%d%d",&b[i].op,&b[i].l,&b[i].r);
scanf("%d",&q);
l=1;r=n;
while(l<r){
mid=(l+r+1)>>1;
if(chk(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
}
int main(){
freopen("sort.in","r",stdin);
freopen("sort.out","w",stdout);
init();
fclose(stdin);
fclose(stdout);
return 0;
}

[bzoj4552][Tjoi2016][Heoi2016]排序的更多相关文章

  1. bzoj千题计划128:bzoj4552: [Tjoi2016&Heoi2016]排序

    http://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案 把>=mid 的数看做1,<mid 的数看做0 这样升序.降序排列相当于 ...

  2. [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)

    解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...

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

    题目链接 BZOJ4552 题解 之前去雅礼培训做过一道题,\(O(nlogn)\)维护区间排序并能在线查询 可惜我至今不能get 但这道题有着\(O(nlog^2n)\)的离线算法 我们看到询问只有 ...

  4. BZOJ4552: [Tjoi2016&Heoi2016]排序

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

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

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

  6. BZOJ4552:[TJOI2016&HEOI2016]排序(线段树,二分)

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

  7. 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)

    传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...

  8. BZOJ4552 Tjoi2016&Heoi2016排序 【二分+线段树】*

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

  9. [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)

    二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...

随机推荐

  1. js点击左右滚动+默认自动滚动类

    js点击左右滚动+默认自动滚动类 点击下载

  2. TP框架中用tp模版迁移smarty模版的注意事项

    ThinkPHP使用Smarty模板引擎的流程及注意事项在多人合作的项目中,Smarty模板使用的最多,具体原因百度. 而ThinkPHP中默认使用的模板是Think自己的模板,这就需要修改默认的模板 ...

  3. CodeSmith 使用说明

    〇.            前言 最近两天自己写了个简单的ORM框架,非常的Easy,但是没有相应的代码生成工具,于是就很杯具了! 于是乎,花费了一天的时间学习并写了一个CodeSmith可以使用的模 ...

  4. R统计分析处理

    [翻译]Awesome R资源大全中文版来了,全球最火的R工具包一网打尽,超过300+工具,还在等什么? 阅读目录 0.前言 1.集成开发环境 2.语法 3.数据操作 4.图形显示 5.HTML部件 ...

  5. Generate Parentheses

    Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of ...

  6. Webwork 学习之路【01】Webwork与 Struct 的前世今生

    Struts 1是全世界第一个发布的MVC框架,它由Craig McClanahan在2001年发布,该框架一经推出,就得到了世界上Java Web开发者的拥护,经过长达6年时间的锤炼,Struts ...

  7. CSS 颜色代码大全

    CSS颜色: 转载:http://www.cnblogs.com/axing/archive/2011/04/09/CSS.html

  8. spring boot 自动部署方案

    现在主流的自动部署方案大都是基于Docker的了,但传统的自动部署方案比较适合中小型公司,下面的方案就是比较传统的自动部署方案. 1.为什么需要自动部署 基于微服务的架构,自动部署显得非常重要.因为每 ...

  9. 弱占优策略--Weakly Dominant Strategy

    Weakly Dominant Strategy Equilibrium(均衡). 先说弱占优.一个策略弱占优就是说,无论其他人采取什么样的策略,这个策略的回报都大于等于其他策略的回报.如果所有人都使 ...

  10. Learning to Rank 简介

    转自:http://www.cnblogs.com/kemaswill/archive/2013/06/01/3109497.html,感谢分享! 本文将对L2R做一个比较深入的介绍,主要参考了刘铁岩 ...