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
主席树的模板
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<queue>
#include <iostream>
using namespace std;
const int maxn = 100000;
int n,m,tot;
int a[maxn+10],rt[maxn+10];
struct node
{
int l,r,sum;
}tree[maxn*40];
vector<int>v;
int getid(int x)//获取x在vector里的排序
{
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void build (int l,int r,int &x)//建树
{
x=++tot;
tree[x].sum=0;
if(l==r)return ;
int m=(l+r)>>1;
build(1,m,tree[x].l);//tree[x].l储存的是左区间节点编号
build(m+1,r,tree[x].r);
}
void update(int l,int r,int &x,int y,int k)
{
x=++tot;
tree[x]=tree[y];
tree[x].sum++;//向下更新
if(l==r)//找到叶子结点
return ;
int m=(l+r)>>1;
if(k<=m)
update(1,m,tree[x].l,tree[y].l,k);//如果更新的点在左边,则向左边找
else
update(m+1,r,tree[x].r,tree[y].r,k);//反之右边
}
int query(int l,int r,int x,int y,int k)//查找
{
if(l==r)return l;
int m=(l+r)>>1;
int sum=tree[tree[y].l].sum-tree[tree[x].l].sum;
//得到sum是当前结点左边的后区间减去前一个区间得到中间区间的值的个数
if(k<=sum)
return query(l,m,tree[x].l,tree[y].l,k);
else return query(m+1,r,tree[x].r,tree[y].r,k-sum);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);//n个数,m次查询
v.clear();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
v.push_back(a[i]);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());//去重
int cnt=v.size();
tot=0;
build(1,cnt,rt[0]);//建立空树
for(int i=1;i<=n;i++)
update(1,cnt,rt[i],rt[i-1],getid(a[i]));//建立不同版本的树
while(m--)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
int ans=v[query(1,cnt,rt[l-1],rt[r],x)-1];//得到答案
printf("%d\n",ans);
}
}
return 0;
}