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),若这个 ...
随机推荐
- Mysql框架---HMySql
Java 数据库框架 在我学习java数据库框架的时候,第一个用的是Hibernate,但是到现在,我可能已经快忘记它了,毕竟快两年没有碰的东西,后来一直再用MyBatis.因为它简单. 但是本文不会 ...
- 分布式技术EJB3_分库架构 - 【动力节点官网】北京Java …
分布式技术EJB3_分库架构 - [动力节点官网]北京Java … http://www.bjpowernode.com/xiazai/2220.html <程序天下--EJB JPA数据库持久 ...
- 解决python pip安装提示"not a supported wheel on this platform"
python下载.whl安装文件后使用pip安装有时候会提示报错"xxxxx not a supported wheel on this platform",应该是下载的库文件版本 ...
- uva10163 Storage Keepers
习题9-9 注意前提是最小值最大.很少做两次dp的题. 初始化要细心. #include<iostream> #include<cmath> #include<algor ...
- uva10366 Faucet Flow
每次找到两边离中心最高的板,如果等,再找外围的最高版...画图便于理解两边先找到距离(-1,1)最近的最大值L和R,因为可能存在多个最高的挡板.接着比较两个L和R的大小,相等的话分别分析两边,取最小值 ...
- vue 模块 props
inbody.vue <template> <div> <Breadcrumb :style="{margin: '24px 0'}"> < ...
- VC-基础:常用的安全CRT函数
常用的安全CRT函数 安全CRT(C Runtime Library = C运行时间库)函数,是微软公司对C/C++语言的扩展.它在原来函数名后添加了“_s”后缀:一般返回出错代码:并将原来的函数返回 ...
- 怎么给xshell服务配置密钥远程登陆
xshell密钥登陆 1.找一台测试服务器xiuxiu-test生成密钥对2. cd ./.ssh/ && 把公钥放在~/.ssh/authorized_keys文件中 cat id ...
- Angular 1.x 框架原理
指令生命周期 compile阶段 对dom进行编译,首先(如果有的话)对template进行应用(这个过程只执行一次).然后把当前指令(内部的指令还没被渲染)传递给iElement,接着执行compi ...
- float 和 clear
float 特性1:可以为行内浮动元素设置宽高 <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...