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 n n and m m m ( n n n, m m 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, k s,t,k.
[ s s s, t t t] indicates the interval and k k k indicates the kth big number in interval [ s s s, t t 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 n n的数组,有 m m m次询问,每次询问输入一个区间 [ l , r ] [l,r] [l,r]及一个 k k k,输出区间 [ l , r ] [l,r] [l,r]内第 k k k小的数字。
思路
静态区间第 k k k大(小),主席树板子。
AC代码
#include<stdio.h>
#include<map>
#include<queue>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#define MOD 10000000007
#define N 100005
typedef long long LL;
using namespace std;
typedef struct node{
int lson,rson,va;//va:权值 主席树
}node;
int tot,n,m,te,len,s,t,k;
int a[N],T[N];
node tree[N<<5];
int R[N];
void init()
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);T[i]=a[i];
}
sort(T+1,T+n+1);
len=unique(T+1,T+n+1)-T-1;
}
void build(int &root,int l,int r)
{
root=++tot;
if(l==r)return;
int mid=(l+r)/2;
build(tree[root].lson,l,mid);
build(tree[root].rson,mid+1,r);
return;
}
int find(int target)
{
return lower_bound(T+1,T+len+1,target)-T;
}
void insert(int pre,int &root,int l,int r,int pos)
{
tree[++tot]=tree[pre];root=tot;
if(l==r)
{
tree[root].va++;return;
}
int mid=(l+r)/2;
if(pos>mid) insert(tree[root].rson,tree[root].rson,mid+1,r,pos);else insert(tree[root].lson,tree[root].lson,l,mid,pos);
tree[root].va++;
return;
}
int query(int from,int to,int k,int l,int r)
{
if(l==r)return l;
int sum=tree[tree[to].lson].va-tree[tree[from].lson].va;
int mid=(l+r)/2;
if(k>sum)
return query(tree[from].rson,tree[to].rson,k-sum,mid+1,r);
else
return query(tree[from].lson,tree[to].lson,k,l,mid);
}
int main()
{
scanf("%d",&te);
while(te--)
{
scanf("%d%d",&n,&m);
init();
tot=0;
build(R[0],1,n);
for(int i=1;i<=n;i++) insert(R[i-1],R[i],1,len,find(a[i]));//insert函数实际上是将原始数据离散化后的值插入权值线段树,故此时的l=1,r=离散化后剩余的元素数
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&s,&t,&k);
printf("%d\n",T[query(R[s-1],R[t],k,1,len)]);
}
}
return 0;
}