您的位置:首页 > 其它

HDU 2665 Kth number(归并树写法)

2014-05-26 17:34 218 查看
#include<cstdio>
#include<string>
#define maxn 100001
int n,m,num[maxn],tr[18][maxn],s[maxn],e[maxn],h[maxn],top;
void merge(int height,int a,int b){
if (a==b){
tr[height][a]=num[a];
return;
}
int mid=(a+b)>>1;
merge(height+1,a,mid);
merge(height+1,mid+1,b);
int i=a,j=mid+1,k=a;
while (i<=mid&&j<=b)
if (tr[height+1][i]<tr[height+1][j])  tr[height][k++]=tr[height+1][i++];
else tr[height][k++]=tr[height+1][j++];
while (i<=mid) tr[height][k++]=tr[height+1][i++];
while (j<=b) tr[height][k++]=tr[height+1][j++];
return;
}
void get(int l,int r,int a,int b,int height){
if (l==a&&r==b){
s[top]=l; e[top]=r; h[top++]=height;
return;
}
int mid=(l+r)>>1;
if (b<=mid) return get(l,mid,a,b,height+1);
else if (a>mid) return get(mid+1,r,a,b,height+1);
else{
get(l,mid,a,mid,height+1);
get(mid+1,r,mid+1,b,height+1);
}
return;
}
int search(int x){
int i,k=0;
for (i=0;i<top;i++){
int l=s[i],r=e[i],height=h[i];
while (l<=r){
int mid=(l+r)>>1;
if (tr[height][mid]<=x){
k+=mid-l+1;
l=mid+1;
}
else  r=mid-1;
}
}
return k;
}
void find(int k){
int maxi=n-1,mini=0;
while(mini<maxi){
int mid=(mini+maxi)>>1;
int res=search(tr[0][mid]);
if (res<k) mini=mid+1;
else maxi=mid;
}
printf("%d\n",tr[0][mini]);
return;
}
void solve(){
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&num[i]);
merge(0,0,n-1);
for(int i=0;i<m;i++){
int a,b,k;
scanf("%d %d %d",&a,&b,&k);
top=0;
get(0,n-1,a-1,b-1,0);
find(k);
}
return;
}
int main(){
int test;
scanf("%d",&test);
while (test--)
solve();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: