Kth number
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9213 Accepted Submission(s): 2868
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]
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这道题目网上的题解大多是划分树解法,其实求区间第K大还有一个方法就是可持久化线段树,这里由于给的值可能是负数,必须离散化,而且离散化之后的线段树空间可以开的更小一点防止内存超限#include <iostream> #include <string.h> #include <stdlib.h> #include <algorithm> #include <math.h> #include <stdio.h> #include <map> using namespace std; const int maxn=1e5; int rt[maxn+5]; int ls[maxn*18+5]; int rs[maxn*18+5]; int sum[maxn*18+5]; int b[maxn+5]; int a[maxn+5]; int n,m; int l,r; int p; map<int,int> m1,m2; void update(int &node,int l,int r,int val) { if(!node) { sum[p]=ls[p]=rs[p]=0; node=p; p++; } else { sum[p]=sum[node];ls[p]=ls[node]; rs[p]=rs[node];node=p; p++; } if(l==r) { sum[node]++; return; } sum[node]++; int mid=(l+r)>>1; if(val<=mid) update(ls[node],l,mid,val); else update(rs[node],mid+1,r,val); } int query(int node1,int node2,int l,int r,int k) { if(sum[node2]-sum[node1]<k) return -1; if(l==r) return l; int mid=(l+r)>>1; int num=sum[ls[node2]]-sum[ls[node1]]; if(num>=k) return query(ls[node1],ls[node2],l,mid,k); else return query(rs[node1],rs[node2],mid+1,r,k-num); } int main() { int t; scanf("%d",&t); int s,e,k; while(t--) { l=1e9;r=0; m1.clear(); m2.clear(); scanf("%d%d",&n,&m); p=1; for(int i=1;i<=n;i++) { scanf("%d",&b[i]); a[i]=b[i]; } sort(b+1,b+n+1); for(int i=1;i<=n;i++) { m1[b[i]]=i; m2[i]=b[i]; } l=1,r=n; update(rt[1]=0,l,r,m1[a[1]]); for(int i=2;i<=n;i++) update(rt[i]=rt[i-1],l,r,m1[a[i]]); int ans; for(int i=1;i<=m;i++) { scanf("%d%d%d",&s,&e,&k); ans=query(rt[s-1],rt[e],l,r,k); printf("%d\n",m2[ans]); } } return 0; }