middle(bzoj 2653)
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
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)的更多相关文章
- 【BZOJ2653】Middle(主席树)
[BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...
- 晨跑(bzoj 1877)
Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...
- 洛谷 P3159(BZOJ 2668)[CQOI2012]交换棋子
有一个\(n\)行\(m\)列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第\(i\)行第\(j\)列的格子只能参与\(m[i][j]\)次交换 ...
- 洛谷P1198 [JSOI2008]最大数(BZOJ.1012 )
To 洛谷.1198 最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当 ...
- SHOI 2007 仙人掌图(BZOJ 1023)
1023: [SHOI2008]cactus仙人掌图 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2564 Solved: 1062 Descrip ...
- 飞镖(bzoj 2335)
Description 飞镖是在欧洲颇为流行的一项运动.它的镖盘上分为20个扇形区域,分别标有1到20的分值,每个区域中有单倍.双倍和三倍的区域,打中对应的区域会得到分值乘以倍数所对应的分数.例如打中 ...
- 海拔(bzoj 2007)
Description YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个 正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1) ...
- 分裂游戏(bzoj 1188)
Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...
- 弱题(bzoj 2510)
Description 有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球的概率均为1/M),若这个 ...
随机推荐
- AJPFX简述Object类
Object类是所有类的超类,所有类都拥有Object的方法.其中的toString.equals是对业务模型而言非常常用的方法.a) toString方法当调用System.out.prin ...
- JavaScript——数组的indexOf()方法在IE8中的兼容性问题
昨天在工作中遇到一个问题:数组的indexOf()方法在IE8中无效. 如以下代码在IE8中报错“对象不支持“indexOf”属性或方法”: var arr = [1,2,3]; var index ...
- [BZOJ1045][HAOI2008]糖果传递 数学
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1045 我们假设每一个小朋友的代价为$x[i]$,每一次都从前面一个小朋友那里拿,这种贪心跟 ...
- new操作符具体干了什么
function Func(){ }; var newFunc=new Func (); new共经过了4个阶段 1.创建一个空对象 var obj=new Object(); 2.设置原型链 把 o ...
- 批量部署Hadoop集群环境(1)
批量部署Hadoop集群环境(1) 1. 项目简介: 前言:云火的一塌糊涂,加上自大二就跟随一位教授做大数据项目,所以很早就产生了兴趣,随着知识的积累,虚拟机已经不能满足了,这次在服务器上以生产环境来 ...
- Android小玩意儿-- 从头开发一个正经的MusicPlayer(一)
之前从未接触过音乐播放器这块东西的开发.今天偶然想做一个自己的音乐播放器.算是练练手.既然要做,就要做一个正儿八经的App.很多网上的资料也是模模糊糊,不是很全,现在开始,自己摸索着尝试着一步一步的做 ...
- java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射
java处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的Io类,不过如果文件超大的话,更快的方式是采用MappedByteBuffer. Mapped ...
- hdu 3232 Crossing Rivers 过河(数学期望)
题意:你在点A,目的地是点B,A和B的距离为D.中间隔了好多条河(所有河不会重叠),每条河有3个参数(P,L,V),其中P表示距离A点的长度,L表示河的长度,V表示河里的船的速度.假设每条河中仅有1条 ...
- 善用Object.defineProperty巧妙找到修改某个变量的准确代码位置
我今天的工作又遇到一个难题.前端UI右下角这个按钮被设置为"禁用(disabled)"状态. 这个按钮的可用状态由属性enabled控制.我通过调试发现,一旦下图第88行代码执行完 ...
- magic_quotes_runtime 和 magic_quotes_sybase 的作用
如果启用了 magic_quotes_runtime,大多数返回任何形式外部数据的函数,包括数据库和文本段将会用反斜线转义引号. 如果启用了magic_quotes_sybase,单引号会被单引号转义 ...