题目大意:给定一个长度为n的序列,求当子序列s的左端点在[a,b],右端点在[c,d]时的最大中位数
其中当序列长度为偶数时中位数定义为中间两个数中较大的那个
很难想的一道题 具体题解见 http://blog.csdn.net/acm_cxlove/article/details/8566093 说的很详细
区间处理那里 [b,c]是必选的 [a,b)和(c,d]每段取最大加和 否则re恒>=0
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 20200 using namespace std; struct abcd{ int lmax,rmax,sum; abcd(int x=0) { lmax=rmax=max(x,0); sum=x; } }; abcd operator + (const abcd &x,const abcd &y) { abcd z; z.sum=x.sum+y.sum; z.lmax=max(x.lmax,x.sum+y.lmax); z.rmax=max(y.rmax,y.sum+x.rmax); return z; } struct Tree{ Tree *ls,*rs; abcd seq; }*tree[M],mempool[M*20],*C=mempool; int n,m,ans,a[M]; pair<int,int>b[M]; Tree* New_Node(Tree *_,Tree *__,abcd ___) { C->ls=_; C->rs=__; C->seq=___; return C++; } Tree* Build_Tree(int x,int y) { int mid=x+y>>1; if(x==y) return New_Node( 0x0 , 0x0 , abcd(1) ); Tree *lson=Build_Tree(x,mid); Tree *rson=Build_Tree(mid+1,y); return New_Node(lson,rson,lson->seq+rson->seq); } Tree *Build_Chain(Tree *p,int x,int y,int z) { int mid=x+y>>1; if(x==y) return New_Node( 0x0 , 0x0 , abcd(-1) ); if(z<=mid) { Tree *lson=Build_Chain(p->ls,x,mid,z); return New_Node(lson,p->rs,lson->seq+p->rs->seq); } else { Tree *rson=Build_Chain(p->rs,mid+1,y,z); return New_Node(p->ls,rson,p->ls->seq+rson->seq); } } abcd Get_Ans(Tree *p,int x,int y,int l,int r) { int mid=x+y>>1; if(x==l&&y==r) return p->seq; if(r<=mid) return Get_Ans(p->ls,x,mid,l,r); if(l>mid) return Get_Ans(p->rs,mid+1,y,l,r); return Get_Ans(p->ls,x,mid,l,mid) + Get_Ans(p->rs,mid+1,y,mid+1,r); } bool Judge(int A,int B,int C,int D,int x) { int re=0; re+=Get_Ans(tree[x],1,n,B,C).sum; re+=Get_Ans(tree[x],1,n,A,B-1).rmax; re+=Get_Ans(tree[x],1,n,C+1,D).lmax; return re>=0; } int Bisection(int A,int B,int C,int D) { int l=1,r=n; while(l+1<r) { int mid=l+r>>1; if( Judge(A,B,C,D,mid) ) l=mid; else r=mid; } if( Judge(A,B,C,D,r) ) return r; return l; } int main() { int i,j,q[10]; cin>>n; for(i=1;i<=n;i++) scanf("%d",&b[i].first),b[i].second=i; sort(b+1,b+n+1); for(i=1;i<=n;i++) a[b[i].second]=i; tree[1]=Build_Tree(1,n); for(i=2;i<=n;i++) tree[i]=Build_Chain(tree[i-1],1,n,b[i-1].second); cin>>m; for(i=1;i<=m;i++) { for(j=0;j<4;j++) scanf("%d",&q[j]),q[j]=(q[j]+ans)%n+1; sort(q,q+4); printf("%d\n", ans=b[Bisection(q[0],q[1],q[2],q[3])].first ); } }
原文地址:http://blog.csdn.net/popoqqq/article/details/40303197