Description

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

Input

  第一行序列长度n。
  接下来n行按顺序给出a中的数。
  接下来一行Q。
  然后Q行每行a,b,c,d,我们令上个询问的答案是x(如果这是第一个询问则x=0)。
  令数组q={(a+x)%n,(b+x)%n,(c+x)%n,(d+x)%n}。
  将q从小到大排序之后,令真正的要询问的a=q[0],b=q[1],c=q[2],d=q[3]。
  输入保证满足条件。

Output

  Q行依次给出询问的答案。

Sample Input

5
170337785
271451044
22430280
969056313
206452321
3
3 1 0 2
2 3 1 4
3 1 4 0

271451044
271451044
969056313

Sample Output

 

HINT

  0:n,Q<=100

  1,...,5:n<=2000

  0,...,19:n<=20000,Q<=25000

/*
二分+主席树 (感觉主席树越来越神奇)
首先要明白中位数怎么求,可以二分,当我们二分出一个答案时,把区间中大于这个数标为1,小于则标为-1,求和。。。
对于这道题来说,要是中位数越大越好,如果按照上面的方法,1越多,代表中位数越大,所以二分出答案后,用GSS的方法求RGSS(a,b)+sum(b,c)+LGSS(c,d),
判断是否大于0。
至于怎么快速求出1/-1数组,用主席树维护(?)
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 20010
using namespace std;
int n,m,cnt,ans;
int a[N],id[N],rt[N],sum[N*],lx[N*],rx[N*],son[N*][];
bool cmp(const int &x1,const int &x2){
return a[x1]<a[x2];
}
void pushup(int x){
sum[x]=sum[son[x][]]+sum[son[x][]];
lx[x]=max(lx[son[x][]],sum[son[x][]]+lx[son[x][]]);
rx[x]=max(rx[son[x][]],sum[son[x][]]+rx[son[x][]]);
}
void build(int l,int r,int &rt){
if(l==r){
rt=++cnt;sum[rt]=lx[rt]=rx[rt]=;
return;
}
rt=++cnt;
int mid=l+r>>;
build(l,mid,son[rt][]);
build(mid+,r,son[rt][]);
pushup(rt);
}
void insert(int x,int &y,int l,int r,int pos,int val){
y=++cnt;
sum[y]=sum[x];lx[y]=lx[x];rx[y]=rx[x];
son[y][]=son[x][];son[y][]=son[x][];
if(l==r){
lx[y]=rx[y]=sum[y]=val;
return;
}
int mid=l+r>>;
if(pos<=mid) insert(son[x][],son[y][],l,mid,pos,val);
else insert(son[x][],son[y][],mid+,r,pos,val);
pushup(y);
}
int get_all(int rt,int l,int r,int x,int y){
if(l==x&&r==y) return sum[rt];
int mid=l+r>>;
if(y<=mid) return get_all(son[rt][],l,mid,x,y);
else if(x>mid) return get_all(son[rt][],mid+,r,x,y);
else return get_all(son[rt][],l,mid,x,mid)+get_all(son[rt][],mid+,r,mid+,y);
}
int get_lx(int rt,int l,int r,int x,int y){
if(l==x&&r==y) return lx[rt];
int mid=l+r>>;
if(y<=mid) return get_lx(son[rt][],l,mid,x,y);
else if(x>mid) return get_lx(son[rt][],mid+,r,x,y);
else return max(get_lx(son[rt][],l,mid,x,mid),get_all(son[rt][],l,mid,x,mid)+get_lx(son[rt][],mid+,r,mid+,y));
}
int get_rx(int rt,int l,int r,int x,int y){
if(l==x&&r==y) return rx[rt];
int mid=l+r>>;
if(y<=mid) return get_rx(son[rt][],l,mid,x,y);
else if(x>mid) return get_rx(son[rt][],mid+,r,x,y);
else return max(get_rx(son[rt][],mid+,r,mid+,y),get_all(son[rt][],mid+,r,mid+,y)+get_rx(son[rt][],l,mid,x,mid));
}
bool check(int k,int a,int b,int c,int d){
int sum=;
if(c>b+) sum+=get_all(rt[k],,n-,b+,c-);
sum+=get_rx(rt[k],,n-,a,b);
sum+=get_lx(rt[k],,n-,c,d);
return sum>=;
}
int main(){
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d",&a[i]);id[i]=i;
}
sort(id,id+n,cmp);
build(,n-,rt[]);
for(int i=;i<n;i++)
insert(rt[i-],rt[i],,n-,id[i-],-);
int ord[];
scanf("%d",&m);
while(m--){
scanf("%d%d%d%d",&ord[],&ord[],&ord[],&ord[]);
for(int i=;i<;i++)
ord[i]=(ord[i]+ans)%n;
sort(ord,ord+);
int l=,r=n,mid;
while(l+<r){
mid=l+r>>;
if(check(mid,ord[],ord[],ord[],ord[]))l=mid;
else r=mid;
}
ans=a[id[l]];
printf("%d\n",ans);
}
return ;
}

middle(bzoj 2653)的更多相关文章

  1. 【BZOJ2653】Middle(主席树)

    [BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...

  2. 晨跑(bzoj 1877)

    Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...

  3. 洛谷 P3159(BZOJ 2668)[CQOI2012]交换棋子

    有一个\(n\)行\(m\)列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第\(i\)行第\(j\)列的格子只能参与\(m[i][j]\)次交换 ...

  4. 洛谷P1198 [JSOI2008]最大数(BZOJ.1012 )

    To 洛谷.1198 最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当 ...

  5. SHOI 2007 仙人掌图(BZOJ 1023)

    1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2564  Solved: 1062 Descrip ...

  6. 飞镖(bzoj 2335)

    Description 飞镖是在欧洲颇为流行的一项运动.它的镖盘上分为20个扇形区域,分别标有1到20的分值,每个区域中有单倍.双倍和三倍的区域,打中对应的区域会得到分值乘以倍数所对应的分数.例如打中 ...

  7. 海拔(bzoj 2007)

    Description YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个 正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1) ...

  8. 分裂游戏(bzoj 1188)

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...

  9. 弱题(bzoj 2510)

    Description 有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球的概率均为1/M),若这个 ...

随机推荐

  1. 导Excel数据表

    需要把EXcel转换格式:

  2. js深拷贝与浅拷贝的区别及实现

    1. 对于基本数据类型 其值在内存中占据着固定大小的空间,并被保存在栈内存中.当一个变量向另一个变量复制基本类型的值,会创建这个值的副本,并且我们不能给基本数据类型的值添加属性.其为深拷贝. 2. 对 ...

  3. (转)@Autowire注解与自动装配

    http://blog.csdn.net/yerenyuan_pku/article/details/52860713 前面我们已经学会使用@Resource注解注入属性,并且我们还编码剖析了@Res ...

  4. DBMS的工作模式

    数据库管理系统(DBMS)是指数据库系统中对数据进行管理的软件系统,它是数据库系统的核心组成部分,对数据库的一切操作(增删改查)都是通过DBMS进行的 DBMS的工作模式如下: 1>接受应用程序 ...

  5. axios添加了header信息后发送的get请求自动编程option请求了

    axios添加了header信息后发送的get请求自动编程option请求了 webpack 代理转发 Provisional headers are shown 在Vue中如何使用axios跨域访问 ...

  6. 初识WEBGL

    WEBGL (全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一 ...

  7. devops issue

    1.Nginx(refercence:https://zhuanlan.zhihu.com/p/24382606) summary: DJANGO_PROJECT = /home/django/dja ...

  8. luogu P1821 Silver Cow Party

    题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the b ...

  9. Openjudge-百练-4013-踩方格

    这题目是一道深搜的题目,我们写一个递归函数叫Ways(int i, int j ,int n),i j就是当前所处的坐标,我们设置一个visited数组,简称 V . 对于这个数组,首先初始化为零,然 ...

  10. linux批量检测服务器能否ping通和硬盘容量状态并抛出报警的一个脚本-附详细解释

    有一些linux基础,最近刚开始学shell,参考了阿良老师的一个监测服务器硬盘状态的脚本,自己进行了一些扩展,今天比较晚了,后边会把注释放上来,感觉脚本还很不完善,希望大家一起探讨一下,共同学习 2 ...