【集训队互测 2012】Middle
来源:互联网 发布:淘宝违规扣分30分 编辑:程序博客网 时间:2024/06/07 13:43
Description
一个长度为 n 的序列 a ,设其排过序之后为 b ,其中位数定义为 b[n/2] ,其中 a,b 从 0 开始标号 , 除法取下整。
给你一个长度为 n 的序列 s 。回答 Q 个这样的询问 : s 的左端点在 [a,b] 之间 , 右端点在 [c,d] 之间的子序列中 ,最大的中位数。
其中 a
Solution
怎么做
一看到什么中位数,k小数,数据范围又不大,那么就可以二分出一个mid,找出比mid小的个数有多少个。
因为每个数对当前判断的贡献只有是与不是,去或不去,那么用1或-1规划一下就好了。比mid的小的设为-1,否则设为1,那么区间[l…r]中如果中位数为mid那么就是这些1和-1的和加起来≥0。
因为b到c必须要取,所以把区间拆解一下变成[a..b]中的最长后缀和+[a+1…b-1]的和+[c…d]中的最长前缀和。
用什么?
强制在线,那么就是可持久化结构。还支持询问,取max。
可持久化线段树。
Code
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=20007;int i,j,k,l,n,m,ans,data[maxn],u,v,r,mid,num,tt;int root[maxn],q[5];struct node{ int lda,sum,l,r,rda;}t[25000*30],op;struct nod{ int a,b;}a[maxn];bool cmp(nod x,nod y){ return x.a<y.a;}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*10+ch-'0'; ch=getchar(); } return x;}void merge(int x){ t[x].sum=t[t[x].l].sum+t[t[x].r].sum; t[x].lda=max(t[t[x].l].lda,t[t[x].l].sum+t[t[x].r].lda); t[x].rda=max(t[t[x].r].rda,t[t[x].r].sum+t[t[x].l].rda);}void build(int &x,int l,int r){ if(!x)x=++num; if(l==r){ t[x].lda=t[x].sum=t[x].rda=1; } else{ int mid=(l+r)/2; build(t[x].l,l,mid); build(t[x].r,mid+1,r); merge(x); }}void change(int &x,int l,int r,int y){ t[++num]=t[x];x=num; if(l==r){t[x].lda=t[x].sum=t[x].rda=-1;return;} int mid=(l+r)/2; if(y<=mid)change(t[x].l,l,mid,y); else change(t[x].r,mid+1,r,y); merge(x);}node bing(node x,node y){ node z; z.sum=x.sum+y.sum; z.l=x.l;z.r=y.r; z.lda=max(x.lda,x.sum+y.lda); z.rda=max(y.rda,y.sum+x.rda); return z;}node find(int x,int l,int r,int y,int z){ if(y>z)return op; if(l==y&&r==z){ return t[x]; } else{ int mid=(l+r)/2; if(z<=mid)return find(t[x].l,l,mid,y,z); else if (y>mid)return find(t[x].r,mid+1,r,y,z); else{ return bing(find(t[x].l,l,mid,y,mid),find(t[x].r,mid+1,r,mid+1,z)); } }}int pan(int x){ return find(root[x],1,n,q[1],q[2]).rda+find(root[x],1,n,q[2]+1,q[3]-1).sum +find(root[x],1,n,q[3],q[4]).lda; }int main(){ n=read(); fo(i,1,n){ a[i].a=read(); a[i].b=i; } sort(a+1,a+1+n,cmp); build(root[1],1,n); fo(i,2,n){ root[i]=root[i-1]; change(root[i],1,n,a[i-1].b); } m=read(); fo(i,1,m){ k=read();tt=read();u=read();v=read(); q[1]=(k+ans)%n+1;q[2]=(tt+ans)%n+1;q[3]=(u+ans)%n+1;q[4]=(v+ans)%n+1; sort(q+1,q+5); l=1,r=n; while(l<r){ mid=(l+r+1)/2; int pp=pan(mid); if(pp>=0)l=mid;else r=mid-1; } ans=a[l].a; printf("%d\n",ans); }}
1 0
- 【集训队互测 2012】Middle
- 【集训队互测 2012】Middle
- 【主席树】2012集训队互测 Middle
- 【jzoj2902】【集训队互测 2012】【Middle】【可持久化线段树】
- [2012集训队互测]JZPKIL
- 【集训队互测2013】城市规划
- 【集训队互测2013】城市规划
- [2015国家集训队互测]口胡
- 【集训队互测2013】供电网络
- UOJ 88 [集训队互测2015]Robot
- [NTT][JZOJ3303]【集训队互测2013】城市规划
- 【UOJ 191/集训队互测】Unknown
- JZOJ2904 【集训队互测 2012】Calc 用倍增的思路转移dp
- [UOJ191][集训队互测2016]Unknown-线段树-斜率优化
- [国家集训队2012]tree(伍一鸣)
- 【国家集训队2012】【BZOJ2654】tree
- 【国家集训队2012】tree(伍一鸣)
- [国家集训队2012]tree(陈立杰)
- html5 touch事件实现触屏页面上下滑动(一)
- Android中实现图片的自动下落与上升
- Plan To Do
- EFI引导及GPT分区
- 欢迎使用CSDN-markdown编辑器
- 【集训队互测 2012】Middle
- 大数相加方法------2
- CNN初探
- 图像特征提取方法
- 安装Win7与Ubuntu双系统
- I/O笔记
- windows下的theano以及GPU加速环境的搭建
- 集成手机归属地查询
- 经典算法——数组的循环右移K位