题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4552

题意:给出一个$1$到$N$的全排列,对其进行$M$次排序,每次排序将区间$[l,r]$从小到大或从大到小排序,求排序完后位置$q$上的数字。$N,M \leq 10^5$,时限$6s$


名字挂羊头卖狗肉……

暴力排序$O(NMlogN)$神级常数才能过,故考虑在排序上降低复杂度

考虑二分答案,将小于等于当前答案的设为$0$,大于当前答案的设为$1$,这样修改就变成$0,1$排序,可以使用线段树区间覆盖实现

时间复杂度$O(Mlog^2N)$

 #include<bits/stdc++.h>
 #define MAXN 100005
 using namespace std;
 inline int read(){
     ;
     char c = getchar();
     while(!isdigit(c))
         c = getchar();
     while(isdigit(c)){
         a = (a << ) + (a << ) + (c ^ ');
         c = getchar();
     }
     return a;
 }

 struct node{
     int l , r , mark , num1;
 }Tree[MAXN << ];
 ] , M , askNum , mid;

 inline void pushup(int dir){
     Tree[dir].num1 = Tree[dir << ].num1 + Tree[dir <<  | ].num1;
 }

 inline void pushdown(int dir){
     )
         Tree[dir << ].mark = Tree[dir <<  | ].mark = Tree[dir << ].num1 = Tree[dir <<  | ].num1 = ;
     else
         ){
             Tree[dir << ].mark = Tree[dir <<  | ].mark = ;
             Tree[dir << ].num1 = Tree[dir << ].r - Tree[dir << ].l + ;
             Tree[dir <<  | ].num1 = Tree[dir <<  | ].r - Tree[dir <<  | ].l + ;
         }
     Tree[dir].mark = -;
 }

 void init(int l , int r , int dir){
     Tree[dir].l = l;
     Tree[dir].r = r;
     Tree[dir].mark = -;
     if(l == r)
         Tree[dir].num1 = num[l] > mid;
     else{
         init(l , l + r >>  , dir << );
         init((l + r >> ) +  , r , dir <<  | );
         pushup(dir);
     }
 }

 void change(int l , int r , int dir , int mark){
     if(Tree[dir].l >= l && Tree[dir].r <= r){
         Tree[dir].mark = mark;
         Tree[dir].num1 = mark * (Tree[dir].r - Tree[dir].l + );
         return;
     }
     pushdown(dir);
     )
         change(l , r , dir <<  , mark);
     )
         change(l , r , dir <<  |  , mark);
     pushup(dir);
 }

 int ask(int l , int r , int dir){
     if(Tree[dir].l >= l && Tree[dir].r <= r)
         return Tree[dir].num1;
     ;
     pushdown(dir);
     )
         sum += ask(l , r , dir << );
     )
         sum += ask(l , r , dir <<  | );
     return sum;
 }

 inline bool check(){
     init( , N , );
      ; i <= M ; i++){
         ] , sortNum[i][] , );
         ]){
             change(sortNum[i][] , sortNum[i][] + t -  ,  , );
             ] + t <= sortNum[i][])
                 change(sortNum[i][] + t , sortNum[i][] ,  , );
         }
         else{
             change(sortNum[i][] - t + ,  sortNum[i][] ,  , );
             ] - t >= sortNum[i][])
                 change(sortNum[i][] , sortNum[i][] - t ,  , );
         }
     }
     );
 }
 int main(){
     N = read();
     M = read();
      ; i <= N ; i++)
         num[i] = read();
      ; i <= M ; i++){
         sortNum[i][] = read();
         sortNum[i][] = read();
         sortNum[i][] = read();
     }
     askNum = read();
      , r = N;
     while(l < r){
         mid = l + r >> ;
         if(check())
             r = mid;
         else
             l = mid + ;
     }
     cout << l;
     ;
 }

BZOJ4552 HEOI/TJOI2016 排序 线段树、二分答案的更多相关文章

  1. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

  2. 洛谷$P2824\ [HEOI2016/TJOI2016]$ 排序 线段树+二分

    正解:线段树+二分 解题报告: 传送门$QwQ$ 昂着题好神噢我$jio$得$QwQQQQQ$,,, 开始看到长得很像之前考试题的亚子,,,然后仔细康康发现不一样昂$kk$,就这里范围是$[1,n]$ ...

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

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

  4. [HEOI2016/TJOI2016]排序 线段树+二分

    [HEOI2016/TJOI2016]排序 内存限制:256 MiB 时间限制:6000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而 ...

  5. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

  6. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

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

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

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

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

  9. BZOJ.4552.[HEOI2016/TJOI2016]排序(线段树合并/二分 线段树)

    题目链接 对于序列上每一段连续区间的数我们都可以动态开点建一棵值域线段树.初始时就是\(n\)棵. 对于每次操作,我们可以将\([l,r]\)的数分别从之前它所属的若干段区间中分离出来,合并. 对于升 ...

随机推荐

  1. WebLogic登录管理控制台、以及相关问题解决

    1.控制台的登录 登录地址是: http://管理实例IP:端口号/console 其中,管理实例的IP或者是管理实例所在主机的主机名 端口号默认7001 因此通过http://localhost:7 ...

  2. Java并发编程(一)线程定义、状态和属性

    一 .线程和进程 1. 什么是线程和进程的区别: 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.在java语言中,线程有四种状态:运行 .就绪.挂起和结束. 进程是指一段正在执行的程序.而 ...

  3. 【Java入门提高篇】Day24 Java容器类详解(七)HashMap源码分析(下)

    前两篇对HashMap这家伙的主要方法,主要算法做了一个详细的介绍,本篇主要介绍HashMap中默默无闻地工作着的集合们,包括KeySet,values,EntrySet,以及对应的迭代器:HashI ...

  4. redis介绍 (8) window 下redis的集群(cluster命令)

    前言: 前段时间我在centos上搭建过一次redis集群,那是借助ruby搭建,这次我介绍一种纯redis集群命令的方式去搭建[最后我会简单介绍ruby搭建]. redis集群搭建(三主三备): 准 ...

  5. 工作中常用到的Vim命令

    最近工作中需要到linux服务器上更改文件,苦于对vim的各种命令不熟悉,今天特此总结并熟悉一下各种vim命令,好提高工作效率.后期持续更新 vim编辑器个人设置 先复制一份vim配置模板到个人目录下 ...

  6. python 定时修改数据库

    当需要定时修改数据库时,一般我们都选择起一个定时进程去改库.如果将这种定时任务写入业务中,写成一个接口呢,定时进程显得有些不太合适?如果需要定时修改100次数据库,常规做法会启动100个进程,虽然这种 ...

  7. 常见问题--post发送参数使用httpservletrequest读取为空

    1)springcloud项目中使用request.getparameter读取参数为空 原因:使用restcontroller导致,之前为controller.而通过requestbody注解封装为 ...

  8. Spring Boot 技术总结

    Spring Boot(一):入门篇 Spring Boot(二):Web 综合开发 Spring Boot(三):Spring Boot 中 Redis 的使用 Spring Boot(四):Thy ...

  9. python中常用函数整理

    1.map map是python内置的高阶函数,它接收一个函数和一个列表,函数依次作用在列表的每个元素上,返回一个可迭代map对象. class map(object): ""&q ...

  10. 模拟开户接口,使用shell脚本实现批量用户开通

    1.目的 通过模拟接口方法,实现批量用户开通 2.分析 A.接口含body和head部分,其中body中的某些变量为必填字段,包含用户的信息,接口可整理成body.xml.head.xml文件. B. ...