【集训队互测 2012】Middle
来源:互联网 发布:淘宝天猫交易额 编辑:程序博客网 时间:2024/06/14 08:57
Description
给出一个序列A,长度为n。给出m次询问,每次询问a,b,c,d(a< b< c< d),求a<=l<=b,c<=r<=d的子序列中,最大的中位数是多少。(这里说的中位数就是中间的那个数)强制在线。
n<=20000,m<=25000
Solution
不知道有什么数据结构能维护中位数。
考虑二分答案,答案x合法就是存在一个序列,使得大于等于x的数的个数大于小于x的数的个数。
那我们可以吧每一个大于等于x的数看做1,小于x的数看做-1。那么一个序列合法就是它的和>=0。
那我们就相当于求一个左端点在[a~b],右端点在[c~d]的最大子段和。
如果这东西>=0,那么答案合法。
这个东西可以拆分成[a~b]的最大后缀和,[b+1~c-1]的和,和[c~d]最大前缀和。
线段树维护。
那么怎么在时限内建树呢?
发现每一个相邻的x的变化只有一条链,于是可以打可持久化线段树。(动态开节点)
Code
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define N 20005using namespace std;struct note{int v,w;}a[N];struct node{int s,lv,rv,l,r;}t[N*30];bool cmp(note x,note y) {return x.v<y.v;}int ans,tot,n,m,x,root[N],q[4];void back(int v) { int x=t[v].l,y=t[v].r; t[v].s=t[x].s+t[y].s; t[v].lv=max(t[x].lv,t[x].s+t[y].lv); t[v].rv=max(t[y].rv,t[y].s+t[x].rv);}node merge(node y,node z) { node x; x.s=y.s+z.s; x.lv=max(y.lv,y.s+z.lv); x.rv=max(z.rv,z.s+y.rv); return x;}void build(int &v,int l,int r) { v=++tot; if (l==r) {t[v].s=t[v].lv=t[v].rv=1;return;} int m=(l+r)/2; build(t[v].l,l,m);build(t[v].r,m+1,r); back(v);}void change(int &v,int l,int r,int x) { t[++tot]=t[v];v=tot; if (l==r) {t[v].s=t[v].lv=t[v].rv=-1;return;} int m=(l+r)/2; if (x<=m) change(t[v].l,l,m,x); else change(t[v].r,m+1,r,x); back(v);}node find(int v,int l,int r,int x,int y) { if (x>y) return t[0]; if (l==x&&r==y) return t[v]; int m=(l+r)/2; if (y<=m) return find(t[v].l,l,m,x,y); else if (x>m) return find(t[v].r,m+1,r,x,y); else return merge(find(t[v].l,l,m,x,m),find(t[v].r,m+1,r,m+1,y));}bool check(int x) { return find(root[x],1,n,q[0],q[1]).rv+find(root[x],1,n,q[1]+1,q[2]-1).s+ find(root[x],1,n,q[2],q[3]).lv>=0;}int main() { scanf("%d",&n); fo(i,1,n) scanf("%d",&a[i].v),a[i].w=i; sort(a+1,a+n+1,cmp); build(root[1],1,n); fo(i,2,n) root[i]=root[i-1],change(root[i],1,n,a[i-1].w); for(scanf("%d",&m);m;m--) { fo(i,0,3) scanf("%d",&x),q[i]=(ans+x)%n+1;sort(q,q+4); int l=1,r=n+1,mid; while (l<r) { mid=(l+r)/2; if (check(mid)) l=mid+1;else r=mid; } printf("%d\n",ans=a[l-1].v); }}
0 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(陈立杰)
- 积木积水(广东工业大学校赛决赛2016E题)
- js跨域数据传输
- C# Winform工程省市县三级行政区联动1 --XML
- Phantomjs 调试方法
- 神经计算的软件整理
- 【集训队互测 2012】Middle
- oracle学习 第二章 限制性查询和数据的排序 ——02
- 深入了解Handler消息机制(二)
- Hbase之Java API使用
- [BZOJ1004] [HNOI2008] Cards - 群论,Burnside引理,Polya定理
- Toolbar的三个问题:修改左边箭头颜色、怎样修改右边以及子activity中的toolbar添加返回箭头
- java笔记——io流
- 了解数据库
- 关于百度,google map的url api的调用