题意:给n个数,每次询问a,b,c,d,你要选定一个区间使得该区间中位数最大,其中a,b为区间左端点可选范围,c,d同理。

OTZ陈老师出的神题。

先考虑一个简单问题:只有一个询问的情况。此时我们二分中位数,并且将区间内小中位数的数标为-1,大于的标为1,此时区间最大和如果大等0,则说明中位数可以变大,然后二分下去就可以了。

加上询问之后,我们就要维护这样一个区间最大和了。考虑主席树,我们对于每一个值,建出它对应的1,-1树,然后二分,到对应的树上去求最大区间和就好了。那么问题来了,怎么维护这样一个最大区间和呢?首先,我们有必选区间b,c所以我要把这个区间的和算上,对于可选区间a,b-1和c+1,d,我们要求一个最大前后缀和。这个东西可以这样求(以前缀和为例):max(左儿子sum+右儿子前缀,左儿子前缀)。

那么整体思路出来了:先建出一棵全线段树(全为1),然后我们把原序列排个序(要把下标对应好),然后一个一个按顺序丢进树里,把小等自己的变为-1,以供这个数的后一个数查询时使用。 然后我们二分答案,对于当前答案去树上找最大区间和,如果大等0则满足条件。

这道题主席树建出来,第一维度是权值,第二维度是下标。我一开始想的一二唯独是反的,而大神说这样有问题,一直没想通哪里有问题。。。再去和大神讨论一下。

写这道题写得异常艰难。先是在想二分会不会有问题(实际是不会的,因为题目弄出来的中位数在偶数个时会选择较大的那个)昨天晚上写了第一版,有点问题,第二天写了第二版,还是有问题,什么没有排序导致没有正确性啊,建树不分配编号啊什么的。然后各种改,终于过了(感谢ihopenot大佬)。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 20005
 4 #define M 400005
 5 #define CT Chairman_Tree
 6 int n,Q,p[5],ans;
 7 struct data{
 8     int num,pos;
 9     bool operator < (const data& w)const{
10         if(num==w.num) return pos<w.pos;
11         return num<w.num;
12     }
13 }a[N];
14 namespace Chairman_Tree{
15     struct node{
16         int son[2],sum,ls,rs;
17     }tr[M];
18     int sz,root[N];
19     void build(int& x,int l,int r){
20         x=++sz;
21         tr[x].ls=tr[x].rs=tr[x].sum=r-l+1;
22         if(l==r) return;
23         int mid=(l+r)>>1;
24         build(tr[x].son[0],l,mid);
25         build(tr[x].son[1],mid+1,r);
26     }
27     void insert(int x,int& y,int l,int r,int lim){
28         tr[y=++sz].sum=tr[x].sum-2;
29         if(l==r){
30             tr[y].ls=tr[y].rs=0;
31             return;
32         }
33         memcpy(tr[y].son,tr[x].son,sizeof(tr[y].son));
34         int mid=(l+r)>>1,LS,RS;
35         if(lim>mid) insert(tr[x].son[1],tr[y].son[1],mid+1,r,lim);
36         else insert(tr[x].son[0],tr[y].son[0],l,mid,lim);
37         LS=tr[y].son[0],RS=tr[y].son[1];
38         tr[y].ls=max(tr[LS].sum+tr[RS].ls,tr[LS].ls);
39         tr[y].rs=max(tr[RS].sum+tr[LS].rs,tr[RS].rs);
40     }
41     inline void insert(int i) {insert(root[i],root[i+1],1,n,a[i].pos);}
42     int query(int x,int L,int R,int l,int r){
43         if(L==l &&     R==r) return tr[x].sum;
44         int mid=(L+R)>>1;
45         if(r<=mid) return query(tr[x].son[0],L,mid,l,r);
46         else if(mid<l) return query(tr[x].son[1],mid+1,R,l,r);
47         else return query(tr[x].son[0],L,mid,l,mid)+query(tr[x].son[1],mid+1,R,mid+1,r);
48     }
49     int lquery(int x,int L,int R,int l,int r){
50         if(L==l && R==r) return tr[x].ls;
51         int mid=(L+R)>>1;
52         if(r<=mid) return lquery(tr[x].son[0],L,mid,l,r);
53         else if(mid<l) return lquery(tr[x].son[1],mid+1,R,l,r);
54         else {
55         int t1=query(tr[x].son[0],L,mid,l,mid)+lquery(tr[x].son[1],mid+1,R,mid+1,r),t2=lquery(tr[x].son[0],L,mid,l,mid);
56         return max(t1,t2);
57         }
58     }
59     int rquery(int x,int L,int R,int l,int r){
60         if(L==l && R==r) return tr[x].rs;
61         int mid=(L+R)>>1;
62         if(r<=mid) return rquery(tr[x].son[0],L,mid,l,r);
63         else if(mid<l) return rquery(tr[x].son[1],mid+1,R,l,r);
64         else {
65         int t1=rquery(tr[x].son[0],L,mid,l,mid)+query(tr[x].son[1],mid+1,R,mid+1,r),t2=rquery(tr[x].son[1],mid+1,R,mid+1,r);
66         return max(t1,t2);
67         }
68     }
69 }
70 using namespace CT;
71 inline int read(){
72     int x=0,f=1; char a=getchar();
73     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
74     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
75     return x*f;
76 }
77 inline bool jud(int x){
78     return rquery(root[x],1,n,p[1],p[2]-1)+query(root[x],1,n,p[2],p[3])+lquery(root[x],1,n,p[3]+1,p[4])>=0;
79 }
80 int main(){
81     n=read();
82     for(int i=1;i<=n;i++) a[i]=(data){read(),i};
83     build(root[1],1,n);
84     sort(a+1,a+1+n);
85     for(int i=1;i<n;i++) insert(i);
86     Q=read();
87     while(Q--){
88         int l=1,r=n;
89         for(int i=1;i<=4;i++) p[i]=(read()+ans)%n+1;
90         sort(p+1,p+5);
91         while(l<r){
92             int mid=(l+r+1)>>1;
93             if(jud(mid)) l=mid;
94             else r=mid-1;
95         }
96         ans=a[l].num; printf("%d\n",ans);
97     }
98     return 0;
99 }

转载于:https://www.cnblogs.com/enigma-aw/p/6202920.html

bzoj2653: middle相关推荐

  1. [BZOJ2653]middle

    [BZOJ2653]middle 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左 ...

  2. BZOJ2653 middle 【主席树】【二分】*

    BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...

  3. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

  4. 【BZOJ2653】middle,主席树(非权值线段树)维护序列和信息+二分答案

    传送门 写在前面:虽然这是一道我再也不想写的题目,但很好很有价值 思路: cxlove大神: 要求中位数最大,首先二分中位数,然后判断可行不可行. 判断X可行不可行,对于区间内的数,凡是>=X的 ...

  5. HDOJ 1157 HDU 1157 Who's in the Middle ACM 1157 IN HDU

    MiYu原创, 转帖请注明 : 转载自 ______________白白の屋   题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1157 题目描述: ...

  6. bzoj 2653 middle (可持久化线段树)

    middle Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 1981  Solved: 1097 [Submit][Status][Discuss] ...

  7. 876. Middle of the Linked List - LeetCode

    为什么80%的码农都做不了架构师?>>>    Question 876. Middle of the Linked List Solution 题目大意:求链表的中间节点 思路:构 ...

  8. Meet in the middle

    搜索是\(OI\)中一个十分基础也十分重要的部分,近年来搜索题目越来越少,逐渐淡出人们的视野.但一些对搜索的优化,例如\(A\)*,迭代加深依旧会不时出现.本文讨论另一种搜索--折半搜索\((meet ...

  9. C语言获取链表的中间值Middle of the Linked List(附完整源码)

    获取链表的中间值Middle of the Linked List node结构体 获取链表的中间值Middle of the Linked List 完整源码(定义,实现,main函数测试) nod ...

最新文章

  1. 面试奇淫巧技之——面试非专业的工作的方法
  2. java keytool 代码_JDK keytool证书工具功能代码解析_java_脚本之家
  3. Docker selenium自动化 - 使用python操作docker,python运行、启用、停用和查询容器实例演示
  4. elasticsearch备份恢复(单机集群)
  5. 动手写了一个12306插件 chrome浏览器
  6. mysql分组查询统计求和
  7. 在浏览器中进行深度学习:TensorFlow.js (二)第一个模型,线性回归
  8. opencv图像分析与处理(4)- 频率域滤波的基础概念
  9. java9新特性有json吗,磨剑三年,跳票一年,Java9新功能有哪些神通?
  10. 三星Samsung ML-2525W 驱动
  11. ColorUI 微信小程序 商品详情页模板,仿微信胶囊
  12. 【模电】0007 有源滤波器2(二阶有源滤低通波器)
  13. HTML+CSS三栏式布局(7种)
  14. 利用Python+xarray+cartopy+matplotlib 实现遥感地形图制图绘制 —— xarray 学习文档01
  15. playhome的php文件怎么导入,PLAY HOME家族崩坏Importor模型导入插
  16. scikit-image图像处理入门
  17. deo.php viewkey,新编粤语读音字典 - 粤语 | Cantonese | 白话 - 声同小语种论坛 - Powered by phpwind...
  18. 【control】微分平坦(Differential Flatness)
  19. MATLAB打开代码,中文注释乱码的解决方法
  20. Rockchip | 使用SD卡启动或升级固件到本地存储

热门文章

  1. mysql中的钱null,mysql 中null总结
  2. QPropertyAnimation实现游戏地图场景变换
  3. python 旋转图像
  4. z变换公式表_各种钣金折弯极限尺寸计算公式汇总,干货!
  5. aboboo 上一句 快捷键_Word快捷键大全
  6. 解决IDEA2020.1版本不兼容Lombok的问题
  7. centos安装mysql5.7.19_Linux下Centos7安装Mysql5.7.19的详细教程
  8. 前端解析Excel文件js-xlsx与bootstrapTable
  9. 数据结构实验之栈与队列四:括号匹配
  10. 【Socket网络编程】15. 发送端和接收端数据大小不一致时 的分析