【题意概述】

  对一个1到n的排列做m次区间排序,最后询问位置q上面的数。

【题解】

  区间排序的效率是nlogn,所以暴力做的话效率是mnlogn,显然达不到要求。

  我们考虑二分答案。如果某个位置的数比mid小,就设为0,如果么某个位置的数大于等于mid,就设为1.  check的时候我们只需对01序列排序就好了,这个可以用线段树做到logn.

  如果排序后位置q的数为1,那么就表示原来这里的数大于等于mid,所以我们要挪动l,否则挪动r.

  总的时间复杂度为m*logn*logn

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define LL long long
  5. #define rg register
  6. #define N 30010
  7. #define ls (u<<1)
  8. #define rs (u<<1|1)
  9. #define len(x) (a[x].r-a[x].l+1)
  10. using namespace std;
  11. int n,m,v[N],l,r,mid,pos;
  12. struct tree{
  13. int l,r,c0,c1,num; bool same;
  14. }a[N<<];
  15. struct opt{
  16. int l,r,type;
  17. }b[N];
  18. inline int read(){
  19. int k=,f=; char c=getchar();
  20. while(c<''||c>'')c=='-'&&(f=-),c=getchar();
  21. while(''<=c&&c<='')k=k*+c-'',c=getchar();
  22. return k*f;
  23. }
  24. void build(int u,int l,int r){
  25. a[u].l=l; a[u].r=r; a[u].same=; a[u].c0=a[u].c1=;
  26. if(l<r){
  27. int mid=(l+r)>>;
  28. build(ls,l,mid); build(rs,mid+,r);
  29. a[u].c0=a[ls].c0+a[rs].c0; a[u].c1=a[ls].c1+a[rs].c1;
  30. }
  31. else{
  32. if(v[l]>=mid) a[u].c1=,a[u].c0=;
  33. else a[u].c0=,a[u].c1=;
  34. }
  35. }
  36. inline void pushdown(int u){
  37. a[u].same=; a[ls].same=a[rs].same=;
  38. a[ls].num=a[rs].num=a[u].num;
  39. if(!a[u].num) a[ls].c0=len(ls),a[ls].c1=,a[rs].c0=len(rs),a[rs].c1=;
  40. else a[ls].c0=,a[ls].c1=len(ls),a[rs].c0=,a[rs].c1=len(rs);
  41. }
  42. void update(int u,int l,int r,int num){
  43. if(l<=a[u].l&&a[u].r<=r){
  44. a[u].same=; a[u].num=num;
  45. if(num==) a[u].c1=len(u),a[u].c0=;
  46. else a[u].c0=len(u),a[u].c1=;
  47. return;
  48. }
  49. if(a[u].same) pushdown(u);
  50. int mid=(a[u].l+a[u].r)>>;
  51. if(l<=mid) update(ls,l,r,num);
  52. if(r>mid) update(rs,l,r,num);
  53. a[u].c0=a[ls].c0+a[rs].c0;
  54. a[u].c1=a[ls].c1+a[rs].c1;
  55. }
  56. int query0(int u,int l,int r){
  57. if(l<=a[u].l&&a[u].r<=r) return a[u].c0;
  58. if(a[u].same) pushdown(u);
  59. int mid=(a[u].l+a[u].r)>>,ret=;
  60. if(l<=mid) ret=query0(ls,l,r);
  61. if(r>mid) ret+=query0(rs,l,r);
  62. return ret;
  63. }
  64. int query1(int u,int l,int r){
  65. if(l<=a[u].l&&a[u].r<=r) return a[u].c1;
  66. if(a[u].same) pushdown(u);
  67. int mid=(a[u].l+a[u].r)>>,ret=;
  68. if(l<=mid) ret=query1(ls,l,r);
  69. if(r>mid) ret+=query1(rs,l,r);
  70. return ret;
  71. }
  72. inline bool check(){
  73. build(,,n); int r0=,r1=;
  74. for(rg int i=;i<=m;i++){
  75. r0=query0(,b[i].l,b[i].r); r1=query1(,b[i].l,b[i].r);
  76. if(b[i].type==) update(,b[i].l,b[i].l+r0-,),update(,b[i].l+r0,b[i].r,);
  77. else update(,b[i].l,b[i].l+r1-,),update(,b[i].l+r1,b[i].r,);
  78. }
  79. r0=query0(,pos,pos); r1=query1(,pos,pos);
  80. return r1>;
  81. }
  82. int main(){
  83. n=read(); m=read();
  84. for(rg int i=;i<=n;i++) v[i]=read();
  85. for(rg int i=;i<=m;i++) b[i].type=read(),b[i].l=read(),b[i].r=read();
  86. pos=read();
  87. l=,r=n+;
  88. while(l+<r){
  89. mid=(l+r)>>;
  90. if(check()) l=mid; else r=mid;
  91. }
  92. printf("%d\n",l);
  93. }

洛谷 2824 [HEOI2016/TJOI2016]排序的更多相关文章

  1. 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告

    P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...

  2. [洛谷P2824][HEOI2016/TJOI2016]排序

    题目大意:一个全排列,两种操作: 1. $0\;l\;r:$把$[l,r]$升序排序2. $1\;l\;r:$把$[l,r]$降序排序 最后询问第$k$位是什么 题解:二分答案,把比这个数大的赋成$1 ...

  3. 洛谷P2824 [HEOI2016/TJOI2016]排序(线段树)

    传送门 这题的思路好清奇 因为只有一次查询,我们考虑二分这个值为多少 将原序列转化为一个$01$序列,如果原序列上的值大于$mid$则为$1$否则为$0$ 那么排序就可以用线段树优化,设该区间内$1$ ...

  4. 洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)

    (另外:题解中有一种思路很高妙而且看上去可以适用一些其他情况的离线方法) 线段树合并&复杂度的简单说明:https://blog.csdn.net/zawedx/article/details ...

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

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

  6. 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP

    洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...

  7. BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治

    原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...

  8. 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告

    P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...

  9. 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告

    P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...

随机推荐

  1. 【168】ENVI入门系列

    参考:ENVI-IDL中国的博客 [ENVI入门系列]01.ENVI产品简介与入门 [ENVI入门系列]02.自定义坐标系(北京54.西安80.2000坐标系) [ENVI入门系列]03.基于自带定位 ...

  2. clc和clear命令的使用

    clc命令是用来清除命令窗口的内容,这点不用多说.不管开启多少个应用程序,命令窗口只有一个,所以clc无论是在脚本m文件或者函数m文件调用时,clc命令都会清除命令窗口的内容.clear命令可以用来清 ...

  3. bzoj 1677: [Usaco2005 Jan]Sumsets 求和【dp】

    设f[i]为i的方案数,f[1]=1,考虑转移,如果是奇数,那么就是f[i]=f[i-1]因为这1一定要加:否则f[i]=f[i-1]+f[i>>1],就是上一位+1或者i/2位所有因子乘 ...

  4. 基于Numpy的神经网络+手写数字识别

    基于Numpy的神经网络+手写数字识别 本文代码来自Tariq Rashid所著<Python神经网络编程> 代码分为三个部分,框架如下所示: # neural network class ...

  5. mysql之distinct

    记录一下这几天看mysql必知必会的小知识点: 关于mysql查询不同的行 比如记录表中 查询有多少个城市 可能查出很多城市 可以用distinct 来解决这个问题 SELECT DISTINCT c ...

  6. Web Api之Cors跨域(干货)---大家一定要看清我写的内容哦

    Web Api之Cors跨域 要想跨域需要准备一下几步骤 1.创建WebAPI(请按照图片先后顺序来) 2.进入NuGet包管理搜 Microsoft.AspNet.WebApi.Cors 进行下载 ...

  7. JavaScript--DOM节点属性

    节点属性 在文档对象模型 (DOM) 中,每个节点都是一个对象.DOM 节点有三个重要的属性 : 1. nodeName : 节点的名称 2. nodeValue :节点的值 3. nodeType ...

  8. jQuery图片区域选择控件_imgAreaSelect

    软考报名时发现可以进行头像区域裁剪功能,F12了一下,发现使用了imgAreaSelect控件. 控件官网: http://odyniec.net/projects/imgareaselect/ 控件 ...

  9. [转]ASP.NET MVC中实现多个按钮提交的几种方法

    本文转自:http://www.cnblogs.com/wuchang/archive/2010/01/29/1658916.html 有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能, ...

  10. EasyUI tree 异步树与采用扁平化实现的同步树

    所谓好记性不如烂笔头,为了以防忘记,才写下这篇博客,废话不多.. 异步树: tips:   可以采用easyui里的原始数据格式,也可以采用扁平化的数据格式. 使用场景: 当菜单模块数量庞大或者无限极 ...