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),若这个 ...
随机推荐
- CF758C Unfair Poll
题意: On the Literature lesson Sergei noticed an awful injustice, it seems that some students are aske ...
- Android Platform Version 和 API Level对照
Platform Version API Level VERSION_CODE Notes Android 5.1 22 LOLLIPOP_MR1 Platform Highlights Androi ...
- JAVA解析XML的几种方法
DOM DOM Document Object Model 文档对象模型.在应用程序中,基于DOM的解析器将一个XML文档转换成一个对象模型的集合(DOM树),应用程序正是通过对这个对象模型的操作,来 ...
- array_keys
<?php$array = array(0 => 100, "color" => "red");print_r(array_keys($arr ...
- http://www.360doc.com/content/10/0928/12/11991_57014502.shtml
http://www.360doc.com/content/10/0928/12/11991_57014502.shtml
- activitymq 集群构建
测试zk是否正常 [root@node2 bin]# cd /zk/1/zookeeper-3.4.10/bin/ [root@node2 bin]# ./zkCli.sh -server 10.50 ...
- 主成分分析、因子分析、ICA(未完成)
并且SVD分解也适用于一般的矩阵. 主成分分析可以简单的总结成一句话:数据的压缩和解释.常被用来寻找判断某种事物或现象的综合指标,并且给综合指标所包含的信息以适当的解释.在实际的应用过程中,主成分分析 ...
- 第三周:Excel
一.Excel的常见函数: 1.文本清洗函数: https://ask.hellobi.com/blog/cbdingchebao/10149
- 微信小程序---代码构成
通过开发者工具快速创建了一个demo项目,观察后可以发现这个项目里边生成了不同类型的文件: .json 后缀的 JSON 配置文件 .wxml 后缀的 WXML 模板文件 .wxss 后缀的 WXSS ...
- python爬虫---实现项目(二) 分析Ajax请求抓取数据
这次我们来继续深入爬虫数据,有些网页通过请求的html代码不能直接拿到数据,我们所需的数据是通过ajax渲染到页面上去的,这次我们来看看如何分析ajax 我们这次所使用的网络库还是上一节的Reques ...