2653: middle

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 2042  Solved: 1123
[Submit][Status][Discuss]

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

Source

我们二分中位数,对于大于mid的数赋值为1,小于mid的数为-1。若最大的区间和大于0则可行。

考虑建一颗主席树(维护权值线段树),root[i]为中位数为i时的前缀树。

二分查询即可。

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 20005
#define ls(i) t[i].s[0]
#define rs(i) t[i].s[1]
using namespace std;
int read() {
int x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
struct tmp {
int v,id;
bool operator <(const tmp tt) const {return v<tt.v;}
}a[maxn];
struct data {
int lm,rm,sum,s[];
}t[maxn*];
int n,q,sz;
int root[maxn];
void pushup(int x) {
t[x].lm=max(t[ls(x)].lm,t[ls(x)].sum+t[rs(x)].lm);
t[x].rm=max(t[rs(x)].rm,t[rs(x)].sum+t[ls(x)].rm);
t[x].sum=t[rs(x)].sum+t[ls(x)].sum;
}
void build(int &rt,int l,int r) {
rt=++sz;
if(l==r) {t[rt].sum=t[rt].lm=t[rt].rm=;return;}
int mid=l+r>>;
build(ls(rt),l,mid);build(rs(rt),mid+,r);
pushup(rt); }
void update(int p,int &rt,int l,int r,int x) {
rt=++sz;
t[rt]=t[p];
if(l==r) {t[rt].sum=-;t[rt].lm=t[rt].rm=;return;}
int mid=l+r>>;
if(x<=mid) update(ls(p),ls(rt),l,mid,x);
else update(rs(p),rs(rt),mid+,r,x);
pushup(rt);
}
int qs(int rt,int l,int r,int x,int y) {
if(x>y) return ;
if(l>=x&&r<=y) return t[rt].sum;
int mid=l+r>>,ans=;
if(x<=mid) ans+=qs(ls(rt),l,mid,x,y);
if(y>mid) ans+=qs(rs(rt),mid+,r,x,y);
return ans;
}
int ql(int rt,int l,int r,int x,int y) {
if(x>y) return ;
if(l>=x&&r<=y) return t[rt].lm;
int mid=l+r>>,ans=;
if(x<=mid) ans=max(ql(ls(rt),l,mid,x,y),ans);
if(y>mid) ans=max(qs(ls(rt),l,mid,x,mid)+ql(rs(rt),mid+,r,x,y),ans);
return ans;
}
int qr(int rt,int l,int r,int x,int y) {
if(x>y) return ;
if(l>=x&&r<=y) return t[rt].rm;
int mid=l+r>>,ans=;
if(x<=mid) ans=max(qs(rs(rt),mid+,r,mid+,y)+qr(ls(rt),l,mid,x,y),ans);
if(y>mid) ans=max(qr(rs(rt),mid+,r,x,y),ans);
return ans;
}
bool check(int x,int q1,int q2,int q3,int q4) {
int s=qs(root[x],,n-,q2,q3)+ql(root[x],,n-,q3+,q4)+qr(root[x],,n-,q1,q2-);
return s>=;
}
int main() {
t[].sum=t[].lm=t[].rm=;
n=read();
for(int i=;i<n;i++) a[i].v=read(),a[i].id=i;
sort(a,a+n);
build(root[],,n-);
for(int i=;i<n;i++) update(root[i-],root[i],,n-,a[i-].id);
int ans=;
q=read();
for(int i=;i<=q;i++) {
int ask[];
for(int j=;j<=;j++) ask[j]=(read()+ans)%n;
sort(ask+,ask+);
int L=,R=n-;
while(L<=R) {
int mid=L+R>>;
if(check(mid,ask[],ask[],ask[],ask[])) L=mid+;
else R=mid-;
}
ans=a[L-].v;
printf("%d\n",ans);
}
}

[BZOJ2653]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(主席树+二分答案)

    传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...

  3. BZOJ 2653: middle 主席树 二分

    https://www.lydsy.com/JudgeOnline/problem.php?id=2653 因为是两个方向向外延伸所以不能对编号取前缀和(这里只有前缀和向后传递的性质,不是实际意义的和 ...

  4. 2018湘潭邀请赛C题(主席树+二分)

    题目地址:https://www.icpc.camp/contests/6CP5W4knRaIRgU 比赛的时候知道这题是用主席树+二分,可是当时没有学主席树,就连有模板都不敢套,因为代码实在是太长了 ...

  5. BZOJ.1926.[SDOI2010]粟粟的书架(前缀和 主席树 二分)

    题目链接 题意: 在给定矩形区域内找出最少的数,满足和>=k.输出数的个数.两种数据范围. 0~50 注意到(真没注意到...)P[i,j]<=1000,我们可以利用前缀和预处理. num ...

  6. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  7. HDU - 4866 主席树 二分

    题意:在x轴\([1,X]\)内的上空分布有n个占据空间\([L_i,R_i]\),高度\(D_i\)的线段,射中线段的得分为其高度,每次询问从x轴的\(x\)往上空射的最近k个线段的总得分,具体得分 ...

  8. POJ 6621: K-th Closest Distance(主席树 + 二分)

    K-th Closest Distance Time Limit: 20000/15000 MS (Java/Others)    Memory Limit: 524288/524288 K (Jav ...

  9. HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)

    HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php? ...

随机推荐

  1. [Elasticsearch] 多字段搜索 (六) - 自定义_all字段,跨域查询及精确值字段

    自定义_all字段 在元数据:_all字段中,我们解释了特殊的_all字段会将其它所有字段中的值作为一个大字符串进行索引.尽管将所有字段的值作为一个字段进行索引并不是非常灵活.如果有一个自定义的_al ...

  2. CSS优化压缩

    顾名思义缩写有简写意思,那就总结一下CSS缩写知识点.为什么要让CSS属性缩写?1.简化代码.一些CSS属性简写可以减少CSS代码从而减少CSS文件的占用字节.加快网页下载速度和网页加载速度.2.优化 ...

  3. MySQL之SELECT 语句详解

    本文参考实验楼的SELECT 语句详解结合自己操作部分而写成. 注意:大多数系统中,SQL语句都是不区分大小写的,但是出于严谨和便于区分保留字和变量名,在书写的时,保留字应大写,而变量名应小写.所谓的 ...

  4. BZOJ3243 [Noi2013]向量内积 【乱搞】

    题目链接 BZOJ3243 题解 模数只有\(2\)或\(3\),可以大力讨论 如果模数为\(2\),乘积结果只有\(1\)或\(0\) 如果一个向量和前面所有向量乘积都为\(1\),那么其和前面向量 ...

  5. RTL2832U+R820T电视棒windows下安装sdr# 以及搭建ADS-B使用VirtualRadar看飞机的教程

    本文中提到的软件随后我会打包给出下载地址.这篇文章是我根据网上的教程和自己的经验修改的详细版本,为了方便入门新手.先来说说RTL2832U+R820T在windows下安装sdr#的方法.首先科普下s ...

  6. 用JSR的@Inject代替@Autowired完成自动装配

    从spring3.0开始spring支持JSR-330 的标准注解.主要是javax.inject这个包下的: 下面的例子用@Inject代替@Autowired.完成自动装配: MovieFinde ...

  7. SQL优化单表案例

    数据准备: -- 创建数据库 mysql> create database db_index_case; Query OK, row affected (0.00 sec) -- 查看数据库 m ...

  8. input 单选按钮radio 取消选中(转载)

    input单选按钮: 在radio按钮中添加属性tag  0代表未被选中 HTML代码: <input name="rdo1" value="AA" ty ...

  9. js如何弹出新窗口

    js如何弹出新窗口 时间:2012-4-22 弹出新窗口也是在网页设计中会经常用到的,其用法也很简单,是通过调用javascript的内置函数windows.open来产生的.  window.ope ...

  10. LOJ 6057 - [HNOI2016]序列 加强版再加强版

    Description 给定一个长度为 \(n\le 3*10^6\) 的序列 \(q\le 10^7\) 次询问每次求区间 \([l,r]\) 的所有子区间的最小值的和 询问随机 Solution ...