查找s,t中中位数。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=100005;
struct pi{
int sum;
int lson;
int rson;
}pp[maxn*18];
int root[maxn],tot;
void build(int cnt,int l,int r){
pp[cnt].sum=0;
if(l==r) return ;
pp[cnt].lson=tot+1;
tot++;
build(tot,l,(l+r)/2);
pp[cnt].rson=tot+1;
tot++;
build(tot,(l+r)/2+1,r);
}
void merg(int qq,int cnt,int n,int p,int k){
int le,ri,mid;
le=1;
ri=n;
while(le<=ri){
mid=(le+ri)/2;
pp[cnt]=pp[qq];
pp[cnt].sum+=k;
if (le==ri) break;
if(p<=mid){
pp[cnt].lson=tot+1;
tot++;
ri=mid;
cnt=tot;
qq=pp[qq].lson;
}
else{
pp[cnt].rson=tot+1;
tot++;
le=mid+1;
cnt=tot;
qq=pp[qq].rson;
}
}
}
int query(int cnt,int le,int ri,int l,int r){
int s=0;
int mid;
if(le>=l&&ri<=r){
return pp[cnt].sum;
}
mid=(le+ri)/2;
if(l<=mid)
s+=query(pp[cnt].lson,le,mid,l,r);
if(r>mid) s+=query(pp[cnt].rson,mid+1,ri,l,r);
return s;
}
int a[maxn],b[maxn];
int get(int l,int r,int n,int k){
int le,ri,mid;
le=1;
ri=n;
while(le<=ri){
mid=(le+ri)/2;
int q=query(root[r],1,n,1,mid)-query(root[l-1],1,n,1,mid);
if(q<k) le=mid+1;
else ri=mid-1;
}
return le;
}
int main()
{
int i,n,m,N=0;
while(cin>>n){
root[0]=0;
tot=0;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
for(i=1;i<=n;i++){
a[i]=(int)(lower_bound(b+1,b+1+n,a[i])-b);
}
for(i=1;i<=n;i++){
root[i]=tot+1;
tot++;
merg(root[i-1],root[i],n,a[i],1);
}
cin>>m;
printf("Case %d:\n",++N);
for(i=0;i<m;i++){
int a,bb,c;
scanf("%d%d",&a,&bb);
c=(bb-a)/2+1;
printf("%d\n",b[get(a,bb,n,c)]);
}
}
}