传送门

题意:

一个长度为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. easyUI返回类型total,rows

  2. [学习OpenCV攻略][011][显示图片]

    学习资料: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html   包含头文件 core.hpp:包含 ...

  3. [国嵌攻略][045-046][一跃进入C大门]

    [一跃进入C大门] 跳转方式 1.相对跳转:b或bl指令,通过计算两个地址之间的差值来给pc赋值相对跳转 2.绝对跳转:ldr指令,通过给pc直接赋值,完成绝对跳转 代码编写 1.在汇编代码中直接使用 ...

  4. PHP安全之webshell和后门检测

    基于PHP的应用面临着各种各样的攻击: XSS:对PHP的Web应用而言,跨站脚本是一个易受攻击的点.攻击者可以利用它盗取用户信息.你可以配置Apache,或是写更安全的PHP代码(验证所有用户输入) ...

  5. YUI 阻止动态css加载

    skinnable动态加载 在YUI Module中,经常采用skinnable参数来动态加载css,如: YUI().use('w-paginator', function(Y) { }, requ ...

  6. MySql Host is blocked because of many connection errors;

    错误:Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' 原因: 同一个i ...

  7. 利用overflow实现导航栏中常 出现的倒三角下拉小图标

    常用网页界面中,导航栏中的倒三角下拉小图标实现,可用overflow: 效果如右图: .Triangle{position:relative;width:280px;height:15px;} ;ov ...

  8. react项目中遇到的坑

    1,touchStart和touchEnd 如果touchstart和touchend改变的是同一个state,那么在首次加载渲染的时候组件会陷入死循环,原因是touchstart会直接触发,但此时s ...

  9. LindDotNetCore~Polly组件对微服务场景的价值

    回到目录 Polly是一个开源框架,在github上可以找到,被善友大哥收录,也是.App vNext的一员! App vNext:https://github.com/App-vNext GitHu ...

  10. 在windows64位Anaconda3环境下安装XGBoost

    安装步骤参考的是: "Installing XGBoost For Anaconda on Windows":https://www.ibm.com/developerworks/ ...