[国家集训队]middle

题目

解法

开\(n\)颗线段树,将第\(i\)颗线段树中大于等于第\(i\)小的数权值赋为1,其他的则为-1,对于每个区间维护一个区间和,最大前缀和,最大后缀和。

然后二分答案,查询二分到的答案对应线段树。

\(设s=[a,b-1]的最大后缀和+[b,c]的区间和+[c+1,d]的最大前缀和\)

若\(s\geq 0\),则答案可能更大,否则答案必须变小,仔细想想为什么。

这样不断二分即可。

考虑到开不下那么多线段树,而若排序后相邻线段树维护的序列只有一个元素不同,所以我们考虑用主席树来维护。

然后其实不需要离散化,离散化也没问题。

完整代码

  1. #include<bits/stdc++.h>
  2. #define rg register
  3. #define il inline
  4. using namespace std;
  5. void ssort(int &a,int &b,int &c,int &d){
  6. if(a>b)swap(a,b);if(a>c)swap(a,c);if(a>d)swap(a,d);
  7. if(b>c)swap(b,c);if(b>d)swap(b,d);
  8. if(c>d)swap(c,d);
  9. }
  10. const int N=3e4;
  11. struct code{
  12. int x,id;
  13. }a[N];
  14. struct tree{
  15. int x,l,r,L,R,sum;
  16. }t[N*100],ans,fz;
  17. int cmp(code x,code y){return x.x<y.x;}
  18. int root[N],cnt,aa,bb,cc,dd,n;
  19. il void pushup(tree &no,tree l,tree r){
  20. no.L=max(l.L,l.sum+r.L);
  21. no.R=max(r.R,r.sum+l.R);
  22. no.sum=l.sum+r.sum;
  23. }
  24. int build(int l,int r){
  25. int no=++cnt;
  26. if(l==r){
  27. t[no].x=t[no].sum=t[no].L=t[no].R=1;
  28. return no;
  29. }
  30. int mid=l+r>>1;
  31. t[no].l=build(l,mid);
  32. t[no].r=build(mid+1,r);
  33. pushup(t[no],t[t[no].l],t[t[no].r]);
  34. return no;
  35. }
  36. int modify(int last,int l,int r,int k){
  37. int no=++cnt;
  38. if(l==r){
  39. t[no].x=t[no].sum=-1;
  40. return no;
  41. }
  42. t[no].l=t[last].l;
  43. t[no].r=t[last].r;
  44. int mid=l+r>>1;
  45. if(k<=mid)t[no].l=modify(t[last].l,l,mid,k);
  46. else t[no].r=modify(t[last].r,mid+1,r,k);
  47. pushup(t[no],t[t[no].l],t[t[no].r]);
  48. return no;
  49. }
  50. void query(int no,int l,int r,int L,int R){
  51. if(l>=L&&r<=R){
  52. pushup(ans,ans,t[no]);
  53. return ;
  54. }
  55. if(l>R||r<L||R<L)return ;
  56. int mid=l+r>>1;
  57. query(t[no].l,l,mid,L,R);
  58. query(t[no].r,mid+1,r,L,R);
  59. }
  60. int check(int x){
  61. int s=0;
  62. ans=fz;query(root[x],1,n,aa,bb-1);s+=ans.R;
  63. ans=fz;query(root[x],1,n,bb,cc);s+=ans.sum;
  64. ans=fz;query(root[x],1,n,cc+1,dd);s+=ans.L;
  65. return s>=0;
  66. }
  67. int main(){
  68. cin>>n;
  69. for(int i=1;i<=n;++i){
  70. scanf("%d",&a[i].x);
  71. a[i].id=i;
  72. }
  73. sort(a+1,a+n+1,cmp);
  74. root[0]=build(1,n);
  75. for(int i=1;i<=n;++i)
  76. root[i]=modify(root[i-1],1,n,a[i].id);
  77. int q,x=0;
  78. cin>>q;
  79. while(q--){
  80. scanf("%d%d%d%d",&aa,&bb,&cc,&dd);
  81. aa=(aa+x)%n+1;bb=(bb+x)%n+1;cc=(cc+x)%n+1;dd=(dd+x)%n+1;
  82. ssort(aa,bb,cc,dd);
  83. int l=0,r=n;
  84. while(l!=r){
  85. int mid=l+r>>1;
  86. if(check(mid+1))l=mid+1;
  87. else r=mid;
  88. }
  89. x=a[l+1].x;
  90. printf("%d\n",x);
  91. }
  92. }

[国家集训队]middle的更多相关文章

  1. [国家集训队]middle 解题报告

    [国家集训队]middle 主席树的想法感觉挺妙的,但是这题数据范围这么小,直接分块草过去不就好了吗 二分是要二分的,把\(<x\)置\(-1\),\(\ge x\)的置\(1\),于是我们需要 ...

  2. P2839 [国家集训队]middle

    P2839 [国家集训队]middle 好妙的题啊,,,, 首先二分一个答案k,把数列里>=k的数置为1,=0就是k>=中位数,<0就是k<中位数 数列的最大和很好求哇 左边的 ...

  3. CF484E Sign on Fence && [国家集训队]middle

    CF484E Sign on Fence #include<bits/stdc++.h> #define RG register #define IL inline #define _ 1 ...

  4. 【LG2839】[国家集训队]middle

    [LG2839][国家集训队]middle 题面 洛谷 题解 按照求中位数的套路,我们二分答案\(mid\),将大于等于\(mid\)的数设为\(1\),否则为\(-1\). 若一个区间和大于等于\( ...

  5. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  6. luogu2839 [国家集训队]middle

    题目链接:洛谷 题目大意:给定一个长度为$n$的序列,每次询问左端点在$[a,b]$,右端点在$[c,d]$的所有子区间的中位数的最大值.(强制在线) 这里的中位数定义为,对于一个长度为$n$的序列排 ...

  7. 解题:国家集训队 Middle

    题面 求中位数的套路:二分,大于等于的设为1,小于的设为-1 于是可以从小到大排序后依次加入可持久化线段树,这样每次只会变化一个位置 那左右端点是区间怎么办? 先把中间的算上,然后维护每个区间左右两侧 ...

  8. [洛谷P2839][国家集训队]middle

    题目大意:给你一个长度为$n$的序列$s$.$Q$个询问,问在$s$中的左端点在$[a,b]$之间,右端点在$[c,d]$之间的子段中,最大的中位数. 强制在线. 题解:区间中位数?二分答案,如果询问 ...

  9. Luogu 2839 [国家集训队]middle

    感觉这题挺好的. 首先对于中位数最大有一个很经典的处理方法就是二分,每次二分一个数组中的下标$mid$,然后我们把$mid$代回到原来的数组中检查,如果一个数$a_{i} \geq mid$,那么就把 ...

随机推荐

  1. extern C的用法解析

    1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言,C++保留了一部分过程式语 ...

  2. Java学习笔记--Java开发坏境搭建

    一.安装JDK http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 根据自己系统选择 ...

  3. 测试计划&性能测试分析报告模板(仅供参考)

    一.测试计划 1. 引言 1.1  编写目的 2. 参考文档 3. 测试目的 4. 测试范围 4.1  测试对象 4.2  需要测试的特性 4.3  无需测试的特性 5. 测试启动与结束准则 5.1  ...

  4. bat输出重定向

    重定向符号主要有:>,>>,<,>&,<&和|,而本文只讨论前五个. 第一节 首先从一个经典问题开始,“1>nul 2>nul”的意思是 ...

  5. R语言入门 :基本数据结构

    1.向量 向量是R语言中最基本的数据类型,在R语言中没有单独的变量. (1)  创建向量 R语言中可以用 = 或者 <- 来赋值. 向量名 <- 向量 或  向量名 = 向量 向量的创建方 ...

  6. 大数据入门第十八天——kafka整合flume、storm

    一.实时业务指标分析 1.业务 业务: 订单系统---->MQ---->Kakfa--->Storm 数据:订单编号.订单时间.支付编号.支付时间.商品编号.商家名称.商品价格.优惠 ...

  7. 20155226 Exp2 后门原理与实践

    20155226 Exp2 后门原理与实践 第一次实验博客交了蓝墨云未在博客园提交,链接 1.Windows获得Linux Shell 在windows下,打开CMD,使用ipconfig指令查看本机 ...

  8. 20155313 杨瀚 《网络对抗技术》实验八 Web基础

    20155313 杨瀚 <网络对抗技术>实验八 Web基础 一.实验目的 1.Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含 ...

  9. 【WPF】WPF截屏

    原文:[WPF]WPF截屏 引言 .NET的截图控件在网上流传得不多啊,难得发现一个精品截图控件( 传送门),但是无奈是winform的.后来又找到一个周银辉做的WPF截图(继续传送门),发现截屏是实 ...

  10. libgdx学习记录23——图片移动选择

    模拟移动选择图片,采用相机实现. package com.fxb.newtest; import com.badlogic.gdx.ApplicationAdapter; import com.bad ...