【bzoj2653】【middle】【主席树+二分答案】
Description
一个长度为 n 的序列 a ,设其排过序之后为 b ,其中位数定义为 b[n/2] ,其中 a,b 从 0 开始标号 , 除法取下整。
给你一个长度为 n 的序列 s 。回答 Q 个这样的询问 : s 的左端点在 [a,b] 之间 , 右端点在 [c,d] 之间的子序列中 ,最大的中位数。
其中 a
Solution
对着题解理解了半天……又对着代码调了半天……最后发现竟然是一个函数名没写orz
不过不得不说这题真的是主席树好题
先考虑二分答案,找出区间内比mid小的数有多少
因为对答案的贡献只有有或没有,所以可以把比mid小的都设为-1,比mid大的都设为1,如果区间内的和大于等于0,说明mid可行,继续二分下去
然而如果离散之后对每一个值建树,空间毫无疑问爆炸
于是只要用主席树维护一下就可以了
//minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char obuf[<<],*o=obuf;
inline void print(int x){
if(x>) print(x/);
*o++=x%+;
}
const int N=,M=N*;
int n,Pre,q,cnt;
int rt[N],p[];
struct node{
int l,r,lmx,rmx,sum;
}t[M],op;
struct data{
int x,id;
inline bool operator <(const data &b)const
{return x<b.x;}
}a[N];
inline void pushup(int x){
t[x].sum=t[t[x].l].sum+t[t[x].r].sum;
t[x].lmx=max(t[t[x].l].lmx,t[t[x].l].sum+t[t[x].r].lmx);
t[x].rmx=max(t[t[x].r].rmx,t[t[x].r].sum+t[t[x].l].rmx);
}
void build(int &now,int l,int r){
now=++cnt;
if(l==r){t[now].lmx=t[now].rmx=t[now].sum=;return;}
int mid=(l+r)>>;
build(t[now].l,l,mid);
build(t[now].r,mid+,r);
pushup(now);
}
void update(int last,int &now,int l,int r,int k){
now=++cnt;
if(l==r){t[now].lmx=t[now].rmx=t[now].sum=-;return;}
int mid=(l+r)>>;
if(k<=mid) t[now].r=t[last].r,update(t[last].l,t[now].l,l,mid,k);
else t[now].l=t[last].l,update(t[last].r,t[now].r,mid+,r,k);
pushup(now);
}
node merge(node x,node y){
node z;
z.sum=x.sum+y.sum;
z.lmx=max(x.lmx,x.sum+y.lmx);
z.rmx=max(y.rmx,y.sum+x.rmx);
return z;
}
node find(int x,int l,int r,int y,int z){
if(y>z) return op;
if(l==y&&r==z) return t[x];
int mid=(l+r)>>;
if(z<=mid) return find(t[x].l,l,mid,y,z);
else if(y>mid) return find(t[x].r,mid+,r,y,z);
else return merge(find(t[x].l,l,mid,y,mid),find(t[x].r,mid+,r,mid+,z));
}
int query(int x){
return find(rt[x],,n,p[],p[]).rmx+find(rt[x],,n,p[]+,p[]-).sum+find(rt[x],,n,p[],p[]).lmx;
}
int main(){
//freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<=n;++i) a[i].x=read(),a[i].id=i;
sort(a+,a++n);
build(rt[],,n);
for(int i=;i<=n;++i) update(rt[i-],rt[i],,n,a[i-].id);
q=read();
while(q--){
int x=read(),y=read(),z=read(),k=read();
p[]=(x+Pre)%n+,p[]=(y+Pre)%n+,p[]=(z+Pre)%n+,p[]=(k+Pre)%n+;
sort(p+,p+);
int l=,r=n,ans=;
while(l<=r){
int mid=(l+r)>>;
int f=query(mid);
if(f>=) ans=mid,l=mid+;
else r=mid-;
}
Pre=a[ans].x;
print(a[ans].x),*o++='\n';
}
fwrite(obuf,o-obuf,,stdout);
return ;
}
【bzoj2653】【middle】【主席树+二分答案】的更多相关文章
- [BZOJ2653]middle 主席树+二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2042 Solved: 1123[Submit][Status][Disc ...
- BZOJ 2653: middle(主席树+二分答案)
传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...
- bzoj 2653: middle (主席树+二分)
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2522 Solved: 1434[Submit][Status][Disc ...
- BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)
BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...
- BZOJ5343[Ctsc2018]混合果汁——主席树+二分答案
题目链接: CTSC2018混合果汁 显然如果美味度高的合法那么美味度低的一定合法,因为美味度低的可选方案包含美味度高的可选方案. 那么我们二分一个美味度作为答案然后考虑如何验证? 选择时显然要贪心的 ...
- P4094 [HEOI2016/TJOI2016]字符串 后缀数组+主席树+二分答案
$ \color{#0066ff}{ 题目描述 }$ 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为n的字符串s,和m个问题.佳媛姐姐必须 ...
- BZOJ 4556 [Tjoi2016&Heoi2016]字符串 ——后缀数组 ST表 主席树 二分答案
Solution 1: 后缀数组暴力大法好 #include <map> #include <cmath> #include <queue> #include &l ...
- HDU - 6621 K-th Closest Distance 主席树+二分答案
K-th Closest Distance 主席树第二波~ 题意 给你\(n\)个数\(m\)个询问,问\(i\in [l,r]\)计算每一个\(|a_{i}-p|\)求出第\(k\)小 题目要求强制 ...
- BZOJ 2653: middle 主席树 二分
https://www.lydsy.com/JudgeOnline/problem.php?id=2653 因为是两个方向向外延伸所以不能对编号取前缀和(这里只有前缀和向后传递的性质,不是实际意义的和 ...
随机推荐
- bzoj1597/luogu2900 土地购买 (斜率优化dp)
首先按x从小到大排序,那么可得: f[i]=min{f[j]+x[i]*maxy[j+1..i]} 然而这样是$O(n^2)$的而且无法做优化. 然后我们考虑:如果对于某一点,存在另一点的x和y都比它 ...
- django restframework Serializers
序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可以将它们轻松地呈现为 JSON,XML 或其他内容类型.序列化器还提供反序列化,在首次验证传入数据之后,可以将 ...
- 【POJ1741】Tree
题目大意:给定一棵 N 个节点的无根树,边有边权,统计树上边权和不大于 K 的路径数. 对于每条树上路径,对于每一个点来说,该路径只有经过该点和不经过该点两种情况,对于不经过该点的情况,可以转化成是否 ...
- redis访问安全加固
目录 redis漏洞 入侵特征 安全隐患 redis安全规范 禁止root用户启动 限制redis文件目录访问权限 开启密码认证,设置复杂密码 禁用或重命名危险命令 设置允许监听地址,不要使用0.0. ...
- 异常处理(throw,throws,try,catch,finally)
一.异常 1.定义:程序在运行时出现的不正确的情况. 2.由来:问题也是生活中的事物,也可以被Java描述,并被封装成对象. 其实就是Java对不正常情况进行描述后的对象体现. 3.划分:Java对于 ...
- QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)
原来有个教程是关于Javamail的,但是那个是自己写Javamail的发送过程,这次不同的是:使用Spring的Mail功能,使用了消息队列. 先看一下设想的场景 不过本文重点不是消息队列,而是使用 ...
- 织梦DedeCMS信息发布员发布文章阅读权限不用审核自动开放亲测试通过!
文章发布员在织梦dedecms后台添加文章时却要超级管理员审核,这无疑是增加了没必要的工作. 登录该账号发布文章你会发现该文章显示的是待审核稿件,且并没有生成静态文件,在前台是看不到这篇文章的,而多数 ...
- 线程的中断.interrupt
线程对象.interrupt() 注意,异常分析中要有break,否则无法中断 public class Demo extends JFrame { private Thread thread;//定 ...
- django基础之数据库操作
Django 自称是“最适合开发有限期的完美WEB框架”.本文参考<Django web开发指南>,快速搭建一个blog 出来,在中间涉及诸多知识点,这里不会详细说明,如果你是第一次接触D ...
- 浅谈分词算法(4)基于字的分词方法(CRF)
目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...