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 and (, <= 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 .
[,] indicates the interval and indicates the kth big number in interval [,]
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
大意一定是我英语不好
给定一个长为的数组,有次询问,每次询问输入一个区间及一个,输出区间内第С的数字。
˼·
静态区间第大(小),主席树板子。
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; }
文章来源: https://blog.csdn.net/weixin_44582673/article/details/97259784