题目大意

给定一个长度为n的序列,有m个操作,操作包括两种:

\(0\ l\ r\)区间[l,r]的数字升序排序

\(1\ l\ r\)区间[l,r]的数字降序排序

最后询问在q位置上的数是多少?

其中\(n \le 100000,m\le 100000\)

QWQ这个题是看了题解才会的,感觉思路很不错

我们考虑,这个题的询问其实只有一组,所以我们可以 二分一个最终在q的数是多少(或者说在原来的排名是多少)

每次将大于等于\(mid\)的数变为1,小于的为0。

那么对于升序排序,假设这个区间有\(tot\)个1,

我们就可以将\([r-tot+1,r]\)赋值为1,将剩余区间赋值为0

而降序排序呢,我们就可以将\([l,l+tot-1]\)赋值为1,其余为0

这样就将“排序“ ---->“区间赋值”:

那么,我们不难想到!!!线段树!!!

只需要最后我们看一下第q个数是不是1就可以,如果是1,我们可以稍微加大mid,不然就减少mid

上代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<map>
  7. #include<queue>
  8. #include<vector>
  9. using namespace std;
  10. inline int read()
  11. {
  12. int x=0,f=1;char ch=getchar();
  13. while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
  14. while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  15. return x*f;
  16. }
  17. const int maxn = 100100;
  18. int f[4*maxn];
  19. int add[4*maxn];
  20. int n,m,a[maxn];
  21. int x[maxn],y[maxn],z[maxn];
  22. int c[maxn];
  23. int l,r;
  24. int ques;
  25. void up(int root)
  26. {
  27. f[root]=f[2*root]+f[2*root+1];
  28. }
  29. void pushdown(int root,int l,int r)
  30. {
  31. int mid = (l+r) >> 1;
  32. if (add[root]!=-1)
  33. {
  34. add[2*root]=add[root];
  35. add[2*root+1]=add[root];
  36. f[2*root]=(mid-l+1)*add[root];
  37. f[2*root+1]=(r-mid)*add[root];
  38. add[root]=-1;
  39. }
  40. }
  41. void build(int root,int l,int r)
  42. {
  43. add[root]=-1;
  44. if (l==r)
  45. {
  46. f[root]=a[l];
  47. return;
  48. }
  49. int mid =(l+r) >> 1;
  50. build(2*root,l,mid);
  51. build(2*root+1,mid+1,r);
  52. up(root);
  53. }
  54. void update(int root,int l,int r,int x,int y,int p)
  55. {
  56. if (l>r || x>y) return;
  57. if (x<=l && r<=y)
  58. {
  59. add[root]=p;
  60. f[root]=(r-l+1)*add[root];
  61. return;
  62. }
  63. pushdown(root,l,r);
  64. int mid = (l+r) >> 1;
  65. if (x<=mid) update(2*root,l,mid,x,y,p);
  66. if (y>mid) update(2*root+1,mid+1,r,x,y,p);
  67. up(root);
  68. }
  69. int query(int root,int l,int r,int x,int y)
  70. {
  71. if (l>r || x>y) return 0;
  72. if (x<=l && r<=y)
  73. {
  74. return f[root];
  75. }
  76. pushdown(root,l,r);
  77. int mid = (l+r) >> 1;
  78. int ans=0;
  79. if (x<=mid) ans=ans+query(2*root,l,mid,x,y);
  80. if (y>mid) ans=ans+query(2*root+1,mid+1,r,x,y);
  81. return ans;
  82. }
  83. bool check(int mid)
  84. {
  85. memset(a,-1,sizeof(a));
  86. for (int i=1;i<=n;i++)
  87. if (c[i]>=mid) a[i]=1;
  88. else a[i]=0;
  89. build(1,1,n);
  90. for (int i=1;i<=m;i++)
  91. {
  92. int tot=query(1,1,n,x[i],y[i]);
  93. if (z[i]==0)
  94. {
  95. update(1,1,n,y[i]-tot+1,y[i],1);
  96. update(1,1,n,x[i],y[i]-tot,0);
  97. }
  98. else
  99. {
  100. update(1,1,n,x[i],x[i]+tot-1,1);
  101. update(1,1,n,x[i]+tot,y[i],0);
  102. }
  103. }
  104. if (query(1,1,n,ques,ques)==1) return true;
  105. else false;
  106. }
  107. int ans;
  108. int main()
  109. {
  110. scanf("%d%d",&n,&m);
  111. l=1;
  112. r=n;
  113. for (int i=1;i<=n;i++) c[i]=read();
  114. for (int i=1;i<=m;i++)
  115. {
  116. z[i]=read();
  117. x[i]=read();
  118. y[i]=read();
  119. }
  120. ques=read();
  121. //二分这个位置上的数是多少
  122. while (l<=r)
  123. {
  124. int mid = (l+r) >> 1;
  125. if (check(mid)) l=mid+1,ans=mid;
  126. else r=mid-1;
  127. }
  128. cout<<ans;
  129. return 0;
  130. }

bzoj4552排序(线段树,二分)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)

    2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...

  8. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  9. luogu4422 [COCI2017-2018#1] Deda[线段树二分]

    讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...

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

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

随机推荐

  1. dotnet C# 给结构体字段赋值非线程安全

    在 dotnet 运行时中,给引用对象进行赋值替换的时候,是线程安全的.给结构体对象赋值,如果此结构体是某个类的成员字段,那么此赋值不一定是线程安全的.是否线程安全,取决于结构体的大小,取决于此结构体 ...

  2. 多个mysql同时运行

    一.准备 mysql下载地址 https://dev.mysql.com/downloads/mysql/ 1.下载 2.解压缩 3.创建my.ini [Client] port = 3307 [my ...

  3. noip模拟48

    A. Lighthouse 很明显的容斥题,组合式与上上场 \(t2\) 一模一样 注意判环时长度为 \(n\) 的环是合法的 B. Miner 题意实际上是要求偶拉路 对于一个有多个奇数点的联通块, ...

  4. appnium显式等待机制

    强制等待: sleep不推荐全局隐式等待 全局隐式等待: 在服务端等待 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); ...

  5. error: object file .git/objects/...

    cd .git find . -type f -empty -delete -print tail -n 2 .git/logs/refs/heads/master git show xxxx(版本号 ...

  6. Linux 配置Maven(避免踩坑篇)

    前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 一.访问Maven官网下载压缩文件. 二.下载好的maven安装包放在磁盘的 /usr/local/ 目录下,如下图: 三.解压该压缩文 ...

  7. ysoserial CommonsColletions4分析

    ysoserial CommonsColletions4分析 其实CC4就是 CC3前半部分和CC2后半部分 拼接组成的,没有什么新的知识点. 不过要注意的是,CC4和CC2一样需要在commons- ...

  8. lua中的sleep实现

    这篇文章主要介绍了Lua中实现sleep函数功能的4种方法,本文讲解了在一个死循环中设置一个跳出条件方法.调用系统的sleep函数法.Windows下ping命令法.socket库中select函数法 ...

  9. 技术栈:springboot2.x,vue,activiti5.22,mysql,带工作流系统

    前言 activiti工作流,企业erp.oa.hr.crm等审批系统轻松落地,请假审批demo从流程绘制到审批结束实例. 一.项目形式 springboot+vue+activiti集成了activ ...

  10. 多线程run()方法是不能够被直接调用的

    操作系统线程的五种状态: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于"可运行 ...