Kth number
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 16080 Accepted Submission(s): 4868
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
2
题意:给一个长为n的数组,m次查询,查询一个区间内的第k大的数。
思路:可持久化线段树
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
int n,m;
int a,b,k;
struct node
{
int chl,chr;
int cnt;
}t[maxn*20];
int root[maxn];
int num[maxn],hah[maxn];
int tot = 0;
void build(int &x,int l,int r) {
x=++tot;
t[x].cnt = 0;
if (l==r) return ;
int mid=(l+r)>>1;
build(t[x].chl,l,mid); build(t[x].chr,mid+1,r);
}
void insert(int &x,int rot,int key,int l,int r) {
x=++tot;
t[x].chl=t[rot].chl;
t[x].chr=t[rot].chr;
t[x].cnt=t[rot].cnt+1;
if (l==r) {
return ;
}
int mid=(l+r)>>1;
if (key>mid) {
insert(t[x].chr,t[rot].chr,key,mid+1,r);
} else {
insert(t[x].chl,t[rot].chl,key,l,mid);
}
}
int query(int a,int b,int l,int r,int k)
{
if(l==r)return l;
int mid = (l+r)>>1;
int sum = t[t[b].chl].cnt - t[t[a].chl].cnt;
if(sum>=k)return query(t[a].chl,t[b].chl,l,mid,k);
else return query(t[a].chr,t[b].chr,mid+1,r,k - sum);
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;i++)
{
scanf("%d",&num[i]);
hah[i] = num[i];
}
sort(hah+1,hah+1+n);
int cnt = unique(hah+1,hah+1+n)-hah-1;
tot = 0;
build(root[0],1,cnt);
for(int i = 1;i<=n;i++)
{
num[i] = lower_bound(hah+1,hah+1+cnt,num[i])-hah;
}
for(int i = 1;i<=n;i++)
{
insert(root[i],root[i-1],num[i],1,cnt);
}
for(int i = 0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&k);
printf("%d\n",hah[query(root[a-1],root[b],1,cnt,k)]);
}
}
}