对百度csdn划分树代码的自己的注释
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int tree[20][100],tolf[20][100],sortt[100];
int maxlevel;
void build(int level,int L,int R)
{
maxlevel=level+1;
if(L==R) return ;
int mid=(L+R)/2;
int g=mid-L+1;//初始化为该到左边去的数量
for(int i=L;i<=R;i++)
{
if(tree[level][i]<sortt[mid])
g--;//遇到能到左边去的数则g-1(用于处理与中位数相等的数)实际到左边去的数
}
int lpos=L,rpos=mid+1;//左右指针
for(int i=L;i<=R;i++)
{
if(i==L) tolf[level][i]=0;
else tolf[level][i]=tolf[level][i-1];//从L遍历到i时到左边去的数的个数
if(tree[level][i]<sortt[mid])
{
tolf[level][i]++;
tree[level+1][lpos++]=tree[level][i];
continue;
}
if(tree[level][i]>sortt[mid])
{
tree[level+1][rpos++]=tree[level][i];
continue;
}
if(tree[level][i]==sortt[mid])
{
if(g!=0)
{
g--;
tolf[level][i]++;
tree[level+1][lpos++]=tree[level][i];
}
else
tree[level+1][rpos++]=tree[level][i];
}
}
build(level+1,L,mid);
build(level+1,mid+1,R);
}
int fin(int level,int L,int R,int ql,int qr,int k)
{
if(ql==qr) return tree[level][ql];
int s;//[L,ql)被分到左边的个数
int ss;//[ql,qr]被分到左边的个数
int mid=(L+R)/2;
if(L==ql)
{
s=0;
ss=tolf[level][qr];
}
else
{
s=tolf[level][ql-1];
ss=tolf[level][qr]-s;
}
if(k<=ss)//查询被分到左边的数
{
//要查询分到左边的数
//节点区间加上分到左边的个数
int newl=L+s;
int newr=L+ss+s-1;
return fin(level+1,L,mid,newl,newr,k);
}
else
{
//查询区间整体右移后减去分到左边的个数
int newl=mid-L+1+ql-s;
int newr=mid-L+1+qr-s-ss;
return fin(level+1,mid+1,R,newl,newr,k-ss);
}
}
int main(void)
{
int n;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&tree[0][i]);
sortt[i]=tree[0][i];
}
sort(sortt+1,sortt+1+n);
build(0,1,n);
/*for(int j=0;j<=maxlevel;j++)
{
printf("tree[%d][]: ",j);
for(int i=1;i<=n;i++)
printf("%4d",tree[j][i]);
printf("\n");
printf("tolf[%d][]: ",j);
for(int i=1;i<=n;i++)
printf("%4d",tolf[j][i]);
printf("\n\n");
}*/
int ql,qr,k;
scanf("%d%d%d",&ql,&qr,&k);
printf("%d\n",fin(0,1,n,ql,qr,k));
}
return 0;
}