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 【主席树】【二分】*的更多相关文章

  1. [BZOJ2653]middle 主席树+二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2042  Solved: 1123[Submit][Status][Disc ...

  2. bzoj 2653: middle (主席树+二分)

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2522  Solved: 1434[Submit][Status][Disc ...

  3. BZOJ 2653: middle(主席树+二分答案)

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

  4. BZOJ 2653: middle 主席树 二分

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

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

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

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

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

  7. 计蒜客 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 ...

  8. HDU - 4866 主席树 二分

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

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

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

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

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

随机推荐

  1. Vue——解决[Vue warn]: Invalid prop: custom validator check failed for prop "index". found in错误

    Invalid prop: custom validator check failed for prop "index". 错误重现: 使用element-ui的菜单,在SubMe ...

  2. Springboot依赖注入笔记

    结合Autowired和Service注解 public interface IUser { void say(); } @Service public class Student implement ...

  3. ubuntu mac terminal install software

    http-server // ubuntu sudo npm install http-server -g npm node.js yarn

  4. 推荐给开发者的11个PHP框架(转)

    PHP框架对于Web开发者来说是非常有用的工具,它可以帮助使用者更快.更容易的完成项目.根据调查,PHP仍是Web开发中最受欢迎和最实用的平台之一.当谈及Web开发时,很多人依然会选择使用PHP框架, ...

  5. 30分钟掌握Dart语言

    在Dart中,一切都是对象,一切对象都是class的实例,哪怕是数字类型.方法甚至null都是对象,所有的对象都是继承自Object 虽然Dart是强类型语言,但变量类型是可选的因为Dart可以自动推 ...

  6. angular2中的路由转场动效

    1.为什么有的人路由转动效离场动效不生效? 自己研究发现是加动效的位置放错了  如下: <---! animate-state.component.html --> <div sty ...

  7. [Vue]组件——使用.native和$listeners将控件的原生事件绑定到组件

    1.方法1:.native修饰符 1.1.native修饰符:将原生事件绑定到组件的根元素上 <base-input v-on:focus.native="onFocus"& ...

  8. PHP stream相关协议及上下文选项和参数归纳

    支持的协议和封装协议 PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen(). copy(). file_exists() 和 filesize() 的文件系统函数. 除了这些封装协 ...

  9. 【程序员笔试面试必会——排序②】Python实现 计数排序、基数排序

    一.计数排序 概要: 时间复杂度O(n),空间复杂度O(k),k是输入序列的值的范围(最大值-最小值),是稳定的.计数排序一般用于已知输入值的范围相对较小,比如给公司员工的身高体重信息排序. 思路: ...

  10. 中国剩余定理——nyoj

    中国剩余定理------解法如下:假设存在一个数M M%A=a , M%B=b , M%C=c并且A,B,C必须俩俩互质.满足这一条件下:存在一个R1使得 , K1=A*B*R1 ,K1%C==1.存 ...