这树着实不好理解啊
讲解http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html
对于找K值 右区间的确定不是太理解。。先当模板贴着吧
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 using namespace std; 7 #define N 100010 8 int tree[20][N],sum[20][N];//每层的数 及每层截止到i会放进左子树的个数 9 int cu[N],xu[N];//原数据 及排序后的数据 10 void build(int c,int l,int r) 11 { 12 int i,m = (l+r)>>1; 13 int o = m-l+1,rp = m+1,lp = l; 14 for(i = l ; i <= m ; i++)//左子树中与xu[m]相同的个数 15 if(xu[i]<xu[m]) 16 o--; 17 for(i = l ; i <= r ; i++) 18 { 19 if(i==l) 20 sum[c][i] = 0; 21 else 22 sum[c][i] = sum[c][i-1];//维护一下 到I为止被分配到左子树中的个数 23 if(tree[c][i]==xu[m]) 24 { 25 if(o) 26 { 27 sum[c][i]++; 28 o--; 29 tree[c+1][lp++] = xu[m];//分配到左子树中 30 } 31 else 32 tree[c+1][rp++] = tree[c][i]; 33 } 34 else if(tree[c][i]<xu[m]) 35 { 36 sum[c][i]++; 37 tree[c+1][lp++] = tree[c][i]; 38 } 39 else 40 tree[c+1][rp++] = tree[c][i];//分配到右子树中 41 } 42 if(l==r) return ; 43 build(c+1,l,m); 44 build(c+1,m+1,r); 45 } 46 int query(int a,int b,int k,int c,int l,int r) 47 { 48 if(l==r) 49 { 50 return tree[c][l]; 51 } 52 int m = (l+r)>>1; 53 int s,ss; 54 if(a==l)//这里特殊处理一下 sum没初始化 不然不处理应该也可以 55 { 56 s = 0; 57 ss = sum[c][b]; 58 } 59 else 60 { 61 s = sum[c][a-1]; 62 ss = sum[c][b]-s; 63 } 64 if(k<=ss) 65 { 66 return query(l+s,l+s+ss-1,k,c+1,l,m); 67 } 68 else 69 return query(m-l+1+a-s,m-l+1+b-s-ss,k-ss,c+1,m+1,r); 70 71 } 72 int main() 73 { 74 int i,n,m; 75 while(scanf("%d%d",&n,&m)!=EOF) 76 { 77 for(i = 1 ; i <= n ; i++) 78 { 79 scanf("%d",&cu[i]); 80 tree[0][i] = cu[i]; 81 xu[i] = cu[i]; 82 } 83 sort(xu+1,xu+n+1); 84 build(0,1,n); 85 while(m--) 86 { 87 int a,b,c; 88 scanf("%d%d%d",&a,&b,&c); 89 int ans = query(a,b,c,0,1,n); 90 printf("%d ",ans); 91 } 92 } 93 return 0; 94 }