BZOJ2653 middle 【主席树】【二分】*
BZOJ2653 middle
Description
一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。给你一个长度为n的序列s。回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c,d]之间的子序列中,最大的中位数。
其中a
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]。
输入保证满足条件。
第一行所谓“排过序”指的是从小到大排序!
n<=20000,Q<=25000
Output
Q行依次给出询问的答案。
Sample Input
5
170337785
271451044
22430280
969056313
206452321
3
3 1 0 2
2 3 1 4
3 1 4 0
Sample Output
271451044
271451044
969056313
这应该算是一道思路题,首先如果对于一个数我们确定了它的值x我们应该怎么做??首先,我们发现所有小于x的数对x是不是中位数的贡献是等价的,同理所有大于x的数对x是不是中位数的贡献是等价的,那么我们可以把所有大于x的数赋值为1,把所有小于x的数赋值为-1,然后我们就可以利用这里的一个性质:当一个区间的最大子段和大于等于0,x一定可以在某种情况下成为中位数,至于为什么。。首先我们发现随着x增大,区间的最大子段和是单调递减的,所以当区间最大子段和大于等于0的时候,当前节点合法,并且显然可能有比它更大的数成为中位数
然后我们考虑怎么对这个区间最大字段和进行维护,首先b~c的节点是必须要选的,我们就维护sum就可以了,然后对于a到b的区间和c到d的区间我们考虑维护最大右子段和和最大左子段和,这些操作都可以在线段树上进行实现,很简单,就不详细说了
那么显然我们是不可能二分每个数然后暴力修改成1和-1的,所以我们考虑将权值作为一个维度,随着权值增加我们修改1的值为-1,这个操作我们可以用主席树实现,我们就根据权值大小来建立主席树,每一棵线段树中以在原序列中的位置作为下标进行维护,然后更新一下,就做完了啦
以前只觉得主席树可以维护一下区间第K大这样板子问题,不知道还可以利用可持久化的性质根据权值的大小来建树,涨姿势了
#include<bits/stdc++.h>
using namespace std;
#define N 20010
#define M 400010
int n,m,cnt=0,tot=0,lastans=0;
int x[N],pre[N],q[5];
int root[N],ls[M],rs[M],sum[M],lsum[M],rsum[M];
vector<int> G[N],p;
map<int,int> mp;
void pushnow(int rt,int vl){sum[rt]=lsum[rt]=rsum[rt]=vl;}
void pushup(int rt){
sum[rt]=sum[ls[rt]]+sum[rs[rt]];
lsum[rt]=max(lsum[ls[rt]],sum[ls[rt]]+lsum[rs[rt]]);
rsum[rt]=max(rsum[rs[rt]],sum[rs[rt]]+rsum[ls[rt]]);
}
void build(int &rt,int l,int r){
rt=++cnt;
if(l==r){pushnow(rt,1);return;}
int mid=(l+r)>>1;
build(ls[rt],l,mid);
build(rs[rt],mid+1,r);
pushup(rt);
}
void modify(int &rt,int last,int l,int r,int pos){
rt=++cnt;
if(l==r){pushnow(rt,-1);return;}
ls[rt]=ls[last];
rs[rt]=rs[last];
int mid=(l+r)>>1;
if(pos<=mid)modify(ls[rt],ls[last],l,mid,pos);
else modify(rs[rt],rs[last],mid+1,r,pos);
pushup(rt);
}
int query_sum(int rt,int l,int r,int ql,int qr){
if(l==ql&&r==qr)return sum[rt];
int mid=(l+r)>>1;
if(qr<=mid)return query_sum(ls[rt],l,mid,ql,qr);
if(ql>mid)return query_sum(rs[rt],mid+1,r,ql,qr);
return query_sum(ls[rt],l,mid,ql,mid)+query_sum(rs[rt],mid+1,r,mid+1,qr);
}
int query_l(int rt,int l,int r,int ql,int qr){
if(l==ql&&r==qr)return lsum[rt];
int mid=(l+r)>>1;
if(qr<=mid)return query_l(ls[rt],l,mid,ql,qr);
if(ql>mid)return query_l(rs[rt],mid+1,r,ql,qr);
int ans=query_l(ls[rt],l,mid,ql,mid);
ans=max(ans,query_sum(ls[rt],l,mid,ql,mid)+query_l(rs[rt],mid+1,r,mid+1,qr));
return ans;
}
int query_r(int rt,int l,int r,int ql,int qr){
if(l==ql&&r==qr)return rsum[rt];
int mid=(l+r)>>1;
if(qr<=mid)return query_r(ls[rt],l,mid,ql,qr);
if(ql>mid)return query_r(rs[rt],mid+1,r,ql,qr);
int ans=query_r(rs[rt],mid+1,r,mid+1,qr);
ans=max(ans,query_sum(rs[rt],mid+1,r,mid+1,qr)+query_r(ls[rt],l,mid,ql,mid));
return ans;
}
bool check(int pos,int a,int b,int c,int d){
int tmp=0;
if(c-b>1)tmp+=query_sum(root[pos],1,n,b+1,c-1);
tmp+=query_l(root[pos],1,n,c,d);
tmp+=query_r(root[pos],1,n,a,b);
return tmp>=0;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&x[i]);
p.push_back(x[i]);
}
sort(p.begin(),p.end());
for(int i=0;i<p.size();i++)
if(!mp[p[i]]){
mp[p[i]]=++tot;
pre[tot]=p[i];
}
for(int i=1;i<=n;i++)G[mp[x[i]]].push_back(i);
build(root[0],1,n);
for(int i=1;i<=tot;i++){
root[i]=root[i-1];
for(int j=0;j<G[i-1].size();j++)
modify(root[i],root[i],1,n,G[i-1][j]);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&q[1],&q[2],&q[3],&q[4]);
for(int j=1;j<=4;j++)q[j]=(q[j]+lastans)%n+1;
sort(q+1,q+5);
int l=1,r=tot,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid,q[1],q[2],q[3],q[4]))l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d\n",lastans=pre[ans]);
}
return 0;
}
BZOJ2653 middle 【主席树】【二分】*的更多相关文章
- [BZOJ2653]middle 主席树+二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2042 Solved: 1123[Submit][Status][Disc ...
- bzoj 2653: middle (主席树+二分)
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2522 Solved: 1434[Submit][Status][Disc ...
- BZOJ 2653: middle(主席树+二分答案)
传送门 解题思路 首先可以想到一种暴力做法,就是询问时二分,然后大于等于这个值的设为1,否则设为-1,然后就和GSS1那样统计答案.但是发现这样时间空间复杂度都很爆炸,所以考虑预处理,可以用主席树来做 ...
- BZOJ 2653: middle 主席树 二分
https://www.lydsy.com/JudgeOnline/problem.php?id=2653 因为是两个方向向外延伸所以不能对编号取前缀和(这里只有前缀和向后传递的性质,不是实际意义的和 ...
- 2018湘潭邀请赛C题(主席树+二分)
题目地址:https://www.icpc.camp/contests/6CP5W4knRaIRgU 比赛的时候知道这题是用主席树+二分,可是当时没有学主席树,就连有模板都不敢套,因为代码实在是太长了 ...
- BZOJ.1926.[SDOI2010]粟粟的书架(前缀和 主席树 二分)
题目链接 题意: 在给定矩形区域内找出最少的数,满足和>=k.输出数的个数.两种数据范围. 0~50 注意到(真没注意到...)P[i,j]<=1000,我们可以利用前缀和预处理. num ...
- 计蒜客 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 ...
- HDU - 4866 主席树 二分
题意:在x轴\([1,X]\)内的上空分布有n个占据空间\([L_i,R_i]\),高度\(D_i\)的线段,射中线段的得分为其高度,每次询问从x轴的\(x\)往上空射的最近k个线段的总得分,具体得分 ...
- POJ 6621: K-th Closest Distance(主席树 + 二分)
K-th Closest Distance Time Limit: 20000/15000 MS (Java/Others) Memory Limit: 524288/524288 K (Jav ...
- HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)
HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php? ...
随机推荐
- linux怎么上真正的国际互联网
1.安装git yum install -y git 2.执行git clone git@github.com:XX-net/XX-Net.git 3.升级python到python 2.7(妈妈说p ...
- 机器学习 delay learning
计蒜之道总决赛考了机器学习,大多数人都不会所以现场学,然后我看了一些之后放弃了..采取了人力分析的办法,最后果然被学习能力碾压.. 不过机器学习看起来是很有趣的,也听别人说了很多,和别人聊了一些,如果 ...
- Sorl初始
Sorl是什么 ? Solr是Apache下的一个开源项目,使用Java基于Lucene开发的全文检索服务:是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可 ...
- 推荐给开发者的11个PHP框架(转)
PHP框架对于Web开发者来说是非常有用的工具,它可以帮助使用者更快.更容易的完成项目.根据调查,PHP仍是Web开发中最受欢迎和最实用的平台之一.当谈及Web开发时,很多人依然会选择使用PHP框架, ...
- ajax实现用户注册
需求分析 页面中给出注册表单: 在username input标签中绑定onblur事件处理函数. 当input标签失去焦点后获取 username表单字段的值,向服务端发送AJAX请求: djang ...
- Mysql解压版配置环境等
背景故事:安装版的mysql和我的本本有仇,最后一步老卡死 1.首先先把下载好的压缩包解压,如下图:
- 第十天 1-9 rhel7-文件的归档和压缩
大纲:文件的归档和压缩1.tar命令的使用及参数解析tar.gz.bz/bz2文件的创建.查看及解压zip/unzip命令的使用 一.文件的归档和压缩 在我们的计算机中,经常会遇到有好多文件名相似或作 ...
- 十九 Python分布式爬虫打造搜索引擎Scrapy精讲—css选择器
css选择器 1. 2. 3. ::attr()获取元素属性,css选择器 ::text获取标签文本 举例: extract_first('')获取过滤后的数据,返回字符串,有一个默认参数,也就是如 ...
- Ubuntu下配置舒服的Python开发环境
Ubuntu 提供了一个良好的 Python 开发环境,但如果想使我们的开发效率最大化,还需要进行很多定制化的安装和配置.下面的是我们团队开发人员推荐的一个安装和配置步骤,基于 Ubuntu 12.0 ...
- echarts在vue中使用的感悟
echarts在vue中使用的感悟 echarts作为图表展示的强大存在,每当使用后台系统,或多或少都会使用到,但是作为菜鸟的我,则是一路采坑,各种头大,比比皆是,为了避免下次再犯同样的错误,特意记录 ...