Kth number
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8007 Accepted Submission(s): 2491
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]
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
和POJ2104一模一样,具体题解看这里: 题解
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 100010
#define lson l,mid,i<<1
#define rson mid+1,r,i<<1|1
vector<int>T[maxn<<2];
void build(int l,int r,int i)//建立线段树,i是节点编号,与区间[l,r)相对应
{
if(l==r)
{
int val;
scanf("%d",&val);
T[i].clear();
T[i].push_back(val);
return ;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
T[i].resize(r-l+1);//调整容器T[i]的大小为 r-l+1
merge(T[i<<1].begin(),T[i<<1].end(),T[i<<1|1].begin(),T[i<<1|1].end(),T[i].begin() );
//将两个儿子的数列合并
}
//计算区间[ql,qr)中不超过val的个数
int query(int ql,int qr,int val,int l,int r,int i)
{
if(ql==l&&qr==r)
return upper_bound(T[i].begin(),T[i].end(),val)-T[i].begin();
int mid=(l+r)>>1;
if(qr<=mid)
return query(ql,qr,val,lson);
else if(ql>mid)
return query(ql,qr,val,rson);
return query(ql,mid,val,lson)+query(mid+1,qr,val,rson);
}
int main()
{
int n,m,a,b,k,c,left,right,mid,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--)
{
scanf("%d%d%d",&a,&b,&k);
left=-1; right=n-1;
while(right-left>1)//二分查找
{
mid=(left+right)>>1;
c=query(a,b,T[1][mid],1,n,1);
if(c>=k)
right=mid;
else
left=mid;
}
printf("%d\n",T[1][right]);
}
}
return 0;
}