静态区间第K大。。
首先应该会 集合第K大的方法。 按值建树,[i,j] 分成【i,p】 【p+1,j】 线段树中的均分。 如果sum(i,p)>=k ,说明第k大在左区间,接下来在左区间找第k大,否则 在右区间找 第k-sum(i,p)大。。
利用可持续数据结构 相减的性质, 每次求出在下标 left 到right ,值在 【i,p】的数的个数。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <cstring>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <assert.h>
#include <queue>
#define REP(i,n) for(int i=0;i<n;i++)
#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define ALLL(x) x.begin(),x.end()
#define SORT(x) sort(ALLL(x))
#define CLEAR(x) memset(x,0,sizeof(x))
#define FILLL(x,c) memset(x,c,sizeof(x))
using namespace std;
const double eps = 1e-9;
#define LL long long
#define pb push_back
const int maxn = 100100;
int n ,m ;
map<int ,int >mp;
map<int ,int >::iterator it;
int idx[maxn];
int num[maxn];
struct Node{
Node *l,*r;
int sum;
}nodes[maxn *25];
Node *root[maxn];
struct Seg{
Node *null;
int C;
void init(){
C = 0 ;
null = &nodes[C++];
null->l = null->r = null;
null->sum = 0;
root[0] = null;
}
Node * update(int pos,int left ,int right ,Node *root,int val){
Node *rt = &nodes[C++];
rt->l = root->l;
rt->r = root->r;
rt->sum = root->sum;
if(left == right){
rt->sum += val;
return rt;
}
int mid = (left + right)/2;
if(pos<= mid){
rt->l = update(pos,left,mid,root->l,val);
}
if(pos>mid){
rt->r = update(pos,mid+1,right,root->r,val);
}
rt->sum = rt->l->sum + rt->r->sum;
return rt;
}
int query(int left ,int right,int k,Node * rroot ,Node * lroot){
if(left ==right){
return left;
}
int mid = (left +right )/2;
int s = rroot->l->sum - lroot->l->sum;
// cout << s << " "<<k<<" "<<left << " "<<right<<endl;
if(s>=k){
return query(left,mid,k,rroot->l,lroot->l);
}else{
return query(mid+1,right,k-s,rroot->r,lroot->r);
}
}
}T;
int main(){
while(~scanf("%d%d",&n,&m)){
mp.clear();
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
mp[num[i]] =1;
}
int tot = 0;
for(it=mp.begin();it!= mp.end();it++){
tot++ ;
it->second = tot;
idx[tot] = it->first;
}
T.init();
for(int i =1;i<=n;i++){
root[i] = T.update(mp[num[i]],1,n,root[i-1],1);
}
for(int i =1;i<=m;i++){
int a,b,k;
scanf("%d%d%d",&a,&b,&k);
int ans = T.query(1,n,k,root[b],root[a-1]);
printf("%d\n",idx[ans]);
}
}
return 0;
}