传送门

题意:

一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。给你一个
长度为n的序列s。回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c,d]之间的子序列中,最大的中位数。
我会使用一些方式强制你在线。

最后一句话太可怕了$QAQ$
首先需要知道怎么求中位数:
二分答案,$\ge$的为$1$,$<$的为$-1$,如果和$\ge 0$说明当前答案$\le$中位数
最大中位数?$GSS$!
只要求$[a,b].rm+(b,c).sum+[c,d].lm$就可以了,注意中间是开区间,$WA$了一次看别人代码才发现
多个询问怎么办?
考虑用线段树维护,离散化后对数值建函数式线段树维护序列,$i$与$i+1$只有一个点不同,只要把$i$置为$-1$就可以了
二分之后到对应的线段树上去求$GSS$
 
PS:重载运算符的节点合并不知道比原来高到哪里去了
 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define lc t[x].l
#define rc t[x].r
#define mid ((l+r)>>1)
#define lson t[x].l,l,mid
#define rson t[x].r,mid+1,r
typedef long long ll;
const int N=2e4+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,Q;
struct Number{
int v,id;
bool operator <(const Number &r)const{return v<r.v;}
}s[N];
struct Node{
int l,r,lm,rm,sum;
Node(){}
Node(int a,int b,int c):lm(a),rm(b),sum(c){}
}t[N*];
int sz,root[N];
inline void merge(int x){
t[x].sum=t[lc].sum+t[rc].sum;
t[x].lm=max(t[lc].lm,t[lc].sum+t[rc].lm);
t[x].rm=max(t[rc].rm,t[rc].sum+t[lc].rm);
}
Node operator +(Node a,Node b){
Node re;
re.sum=a.sum+b.sum;
re.lm=max(a.lm,a.sum+b.lm);
re.rm=max(b.rm,b.sum+a.rm);
return re;
}
void segCha(int &x,int l,int r,int p,int v){
t[++sz]=t[x];x=sz;
if(l==r) t[x].sum=t[x].lm=t[x].rm=v;
else{
if(p<=mid) segCha(lson,p,v);
else segCha(rson,p,v);
merge(x);
}
}
Node segQue(int x,int l,int r,int ql,int qr){
if(ql>qr) return Node(,,);
if(ql<=l&&r<=qr) return t[x];
else{
if(qr<=mid) return segQue(lson,ql,qr);
if(mid<ql) return segQue(rson,ql,qr);
return segQue(lson,ql,qr)+segQue(rson,ql,qr);
}
}
void build(int &x,int l,int r){
t[++sz]=t[x];x=sz;
if(l==r) t[x].sum=t[x].lm=t[x].rm=;
else{
build(lson);
build(rson);
merge(x);
}
}
int a,b,c,d,q[];
int Query(int g){
int x=root[g];
return segQue(x,,n-,a,b).rm+segQue(x,,n-,b+,c-).sum+segQue(x,,n-,c,d).lm;
}
int main(){
freopen("in","r",stdin);
n=read();
for(int i=;i<n;i++) s[i].v=read(),s[i].id=i;
sort(s,s+n);
build(root[],,n-);
for(int i=;i<n;i++) root[i]=root[i-],segCha(root[i],,n-,s[i-].id,-); int last=;
Q=read();//int debug=0;
while(Q--){//printf("debug %d\n",++debug);
for(int i=;i<=;i++) q[i]=(read()+last)%n;
sort(q+,q++);
a=q[];b=q[];c=q[];d=q[];
//printf("abcd %d %d %d %d\n",a,b,c,d);
int l=,r=n-,ans=;
while(l<=r){
int mi=(l+r)>>;
if(Query(mi)>=) ans=mi,l=mi+;
else r=mi-;
}
last=s[ans].v;
printf("%d\n",last);
}
}
 
 

BZOJ 2653: middle [主席树 中位数]的更多相关文章

  1. bzoj 2653: middle (主席树+二分)

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2522  Solved: 1434[Submit][Status][Disc ...

  2. bzoj 2653 middle(主席树)

    题面:https://vjudge.net/problem/HYSBZ-2653 博客:https://blog.csdn.net/litble/article/details/78984846 这个 ...

  3. BZOJ 2653: middle(主席树+二分答案)

    传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...

  4. BZOJ 2653: middle 主席树 二分

    https://www.lydsy.com/JudgeOnline/problem.php?id=2653 因为是两个方向向外延伸所以不能对编号取前缀和(这里只有前缀和向后传递的性质,不是实际意义的和 ...

  5. BZOJ 2653 middle | 主席树

    题目: http://www.lydsy.com/JudgeOnline/problem.php?id=2653 题解: 设答案为ans,把大于等于ans的记为1,小于的记为-1,这样可以知道当前an ...

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

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

  7. bzoj 2653 middle 二分答案 主席树判定

    判断中位数是否可行需要将当前的解作为分界,大于其的置为1,小于为-1,然后b-c必选,ab,cd可不选,这个用线段树判定就好 但不能每次跑,所以套主席树,按权值排序,构建主席树,更新时将上一个节点改为 ...

  8. BZOJ 2653 middle 二分答案+可持久化线段树

    题目大意:有一个序列,包含多次询问.询问区间左右端点在规定区间里移动所得到的最大中位数的值. 考虑对于每个询问,如何得到最优区间?枚举显然是超时的,只能考虑二分. 中位数的定义是在一个序列中,比中位数 ...

  9. [BZOJ2653]middle 主席树+二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2042  Solved: 1123[Submit][Status][Disc ...

随机推荐

  1. A. Vasya and Football

    A. Vasya and Football time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  2. 去除FineReport报表点击单元格时出现的黑框

    选择模版->模版web属性 添加加载结束事件,具体代码如下 $("td").bind("click",function(){return false;}) ...

  3. js根据出生年月日换算年龄

    function age_Conversion(date) { debugger var age = ''; var str = date.replace(/年|月/g, "-") ...

  4. PHP flock() 函数

    定义和用法 flock() 函数锁定或释放文件. 若成功,则返回 true.若失败,则返回 false. 语法 flock(file,lock,block) 参数 描述 file 必需.规定要锁定或释 ...

  5. LNMP一键安装包

    http://www.aliweihu.com/333.html LNMP一键安装包是什么? LNMP一键安装包是一个用Linux Shell编写的可以为CentOS/RadHat.Debian/Ub ...

  6. asp.net -mvc框架复习(11)-基于三层架构与MVC实现完整的用户登录

    一.先从M部分写起(Modles\DAL\BLL) 1.Modles 实体类:上次实体类已经搞定. 2.DAL 数据访问类类 (1)通用数据数据访问类: A:  先编写数据连接字符串,写到网站根目录W ...

  7. Java数据持久层框架 MyBatis之API学习二(入门)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  8. C#如何释放已经加载的图片

    使用Image.FromFile取磁盘上的图片时,这个方法会锁定图片文件,而且会导致内存占用增大, 有几种方法解决:一:将Image类转换成Bitmap类System.Drawing.Image im ...

  9. 使用BIOS进行键盘输入和磁盘读写

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  10. Hystrix-Dashboard仪表盘

    Hystrix Dashboard,它主要用来实时监控Hystrix的各项指标信息.通过Hystrix Dashboard反馈的实时信息,可以帮助我们快速发现系统中存在的问题.下面通过一个例子来学习. ...