博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[bzoj 2653][国家集训队]middle
阅读量:6201 次
发布时间:2019-06-21

本文共 3244 字,大约阅读时间需要 10 分钟。

Description

一个长度为\(n\)的序列\(a\),设其排过序之后为\(b\),其中位数定义为\(b[n/2]\),其中\(a,b\)\(0\)开始标号,除法取下整。

给你一个长度为n的序列\(s\)

回答\(Q\)个这样的询问:\(s\)的左端点在\([a,b]\)之间,右端点在\([c,d]\)之间的子序列中,最大的中位数。

其中\(a<b<c<d\)

位置也从\(0\)开始标号,强制在线

Solution

求中位数有一个很常见的做法,二分一个答案,把大于等于它的数设为\(1\),小于它的数设为\(1\)

这样,如果区间和大于等于\(0\),中位数显然会大于等于当前答案

可以对每个权值都建一个线段树,当然可以用主席树来实现

check的时候,我们显然需要得到区间最大值,对\([a,b]\)求后缀最大值,\([b+1,c-1]\)区间求和,\([c,d]\)求前缀最大值即可

调了很久,一直都是\(95\)分,结果是id[i-1].size-1写成了id[i-1].size,我倒了

Code 

#include
#define ll long long#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))using namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f;}#define MN 20005int n,N,val[MN],nn[MN],root[MN];std::vector
id[MN];struct Node{int ls,rs,lm,rm,s;}t[MN*50];int sz;#define mid ((l+r)>>1)#define lson t[x].ls#define rson t[x].rsinline void up(int x){ t[x].s=t[lson].s+t[rson].s; t[x].rm=max(t[rson].rm,t[lson].rm+t[rson].s); t[x].lm=max(t[lson].lm,t[rson].lm+t[lson].s);}inline void Build(int &x,int l,int r){ x=++sz;if(l==r) return (void)(t[x]=(Node){0,0,1,1,1}); Build(lson,l,mid);Build(rson,mid+1,r);up(x);}inline void Modify(int &x,int l,int r,int p){ t[++sz]=t[x];x=sz; if(l==r){t[x].s=t[x].lm=t[x].rm=-1;return;} p<=mid?Modify(lson,l,mid,p):Modify(rson,mid+1,r,p);up(x);}#define P std::pair
inline P QR(int x,int l,int r,int a,int b){ if(a==l&&r==b) return std::make_pair(t[x].rm,t[x].s); if(b<=mid) return QR(lson,l,mid,a,b); if(a>mid) return QR(rson,mid+1,r,a,b); P L=QR(lson,l,mid,a,mid),R=QR(rson,mid+1,r,mid+1,b); return std::make_pair(max(L.first+R.second,R.first),L.second+R.second);}inline P QL(int x,int l,int r,int a,int b){ if(a==l&&r==b) return std::make_pair(t[x].lm,t[x].s); if(b<=mid) return QL(lson,l,mid,a,b); if(a>mid) return QL(rson,mid+1,r,a,b); P L=QL(lson,l,mid,a,mid),R=QL(rson,mid+1,r,mid+1,b); return std::make_pair(max(R.first+L.second,L.first),L.second+R.second);}inline int QS(int x,int l,int r,int a,int b){ if(a>b) return 0; if(a==l&&r==b) return t[x].s; if(b<=mid) return QS(lson,l,mid,a,b); if(a>mid) return QS(rson,mid+1,r,a,b); return QS(lson,l,mid,a,mid)+QS(rson,mid+1,r,mid+1,b);}inline bool check(int a,int b,int c,int d,int v){ int Ans=QR(root[v],1,n,a,b).first+QS(root[v],1,n,b+1,c-1)+QL(root[v],1,n,c,d).first; return Ans>=0;}int main(){ n=read();register int i,j; for(i=1;i<=n;++i) nn[i]=val[i]=read(); std::sort(nn+1,nn+n+1);N=std::unique(nn+1,nn+n+1)-nn-1; for(i=1;i<=n;++i) val[i]=std::lower_bound(nn+1,nn+N+1,val[i])-nn,id[val[i]].push_back(i); Build(root[1],1,n); for(i=2;i<=N;++i) { root[i]=root[i-1]; for(j=id[i-1].size()-1;~j;--j) Modify(root[i],1,n,id[i-1][j]); } register int Q=read(),a[6],x=0,l,r; while(Q--) { for(i=0;i<4;++i) a[i]=(read()+x)%n+1; std::sort(a,a+4); for(x=l=1,r=N;l<=r;check(a[0],a[1],a[2],a[3],mid)?(x=mid,l=mid+1):r=mid-1); printf("%d\n",x=nn[x]); } return 0;}


Blog来自PaperCloud,未经允许,请勿转载,TKS!

转载于:https://www.cnblogs.com/PaperCloud/p/10273093.html

你可能感兴趣的文章
Linux系统上获取命令帮助信息的方法
查看>>
5-6单元练习题关于用户权限
查看>>
java 组件记录
查看>>
重绘控件软件报错,_CrtDbgBreak()
查看>>
最近在北京做银行软件项目亲身感受小总结
查看>>
svn服务器的配置
查看>>
MBProgressHUD的基本使用
查看>>
elk 简单实用
查看>>
学习大数据课程必须了解的大数据开发课程大纲
查看>>
计算机中十进制转二进制的相关技巧
查看>>
阿里云异构计算发布:轻量级GPU云服务器实例VGN5i
查看>>
植树节活动策划主题班会PPT
查看>>
UEFI启动模式的服务器使用U盘安装Linux系统
查看>>
供应链支付电商流程图是什么样的?如何绘制
查看>>
企业wifi管家——让天下没有难管的wifi
查看>>
项目中遇到地图显示问题的整理和解决(针对百度地图)
查看>>
砺鹰教育紧紧跟随“互联网+教育”助力优质教育资源共享
查看>>
《pro git》学习手记2
查看>>
Linux互信及互信失效问题
查看>>
一年前生了个娃
查看>>