地址:http://acm.hdu.edu.cn/showproblem.php?pid=2665
Kth number
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3421 Accepted Submission(s): 1148
Problem Description
Give you a sequence and ask you the kth big number of a inteval.
Input
The first line is the number of the test cases.
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
Output
For each test case, output m lines. Each line contains the kth big number.
Sample Input
1 10 1 1 4 2 3 5 6 7 8 9 0 1 3 2
Sample Output
2
利用划分树
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define M 100010
int tr[20][M],num[20][M],sorted[M];
void ori_tree(int l,int r,int c) //建树
{
if(l==r) return ;
int m=(l+r)/2;
int lp=l;int rp=m+1;
int h=1;
for(int j=m-1;j>=l;j--)
{
if(sorted[j]==sorted[m]) h++;
else break;
}
for(int i=l;i<=r;i++)
{
num[c][i]=num[c][i-1];
if(tr[c][i]<sorted[m]&&lp<=m)
{
num[c][i]++;
tr[c+1][lp++]=tr[c][i];
}
else if(tr[c][i]==sorted[m])
{
if(h>0)
{
num[c][i]++;
tr[c+1][lp++]=tr[c][i];
h--;
}
else tr[c+1][rp++]=tr[c][i];
}
else tr[c+1][rp++]=tr[c][i];
}
ori_tree(l,m,c+1);
ori_tree(m+1,r,c+1);
}
int query(int s,int e,int k,int l,int r,int c) //查找
{
int m=(l+r)/2;
if(l==r)
return tr[c][s];
int p=num[c][e]-num[c][s-1];
int q=num[c][s-1]-num[c][l-1];
if(p>=k)
return query(l+q,l+q+p-1,k,l,m,c+1);
else
{
int b=s-l-q; int bb=e-s+1-p;
return query( m+b+1,m+b+bb,k-p,m+1,r,c+1);
}
}
int main()
{
int t,m,n,i,j,s,e,k,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&n);
memset(num,0,sizeof(num));
memset(tr,0,sizeof(tr));
for(i=1;i<=m;i++)
{
scanf("%d",&tr[0][i]);
sorted[i]=tr[0][i];
}
sort(sorted+1,sorted+m+1);
ori_tree(1,m,0);
while(n--)
{
scanf("%d%d%d",&s,&e,&k);
ans=query(s,e,k,1,m,0);
printf("%d\n",ans);
}
}
return 0;
}