poj 2104
区间k大 不修改 只查询 模板
#include<iostream>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 240008
#define M 5500000
using namespace std;
int n,m,rt[N];
struct Node{
int l,r,cnt;;
}tr[N<<4];
int cur;
void pushup(int x)
{
int l=tr[x].l,r=tr[x].r;
tr[x].cnt=tr[l].cnt + tr[r].cnt;
}
inline void apushup(int o) {
tr[o].cnt = tr[tr[o].l].cnt + tr[tr[o].r].cnt;
}
int build(int l,int r ) {
int k = cur++;
if (l == r) {
tr[k].cnt = 0;
return k;
}
int mid = (l + r) >> 1;
tr[k].l = build(l, mid);
tr[k].r = build(mid + 1, r);
pushup(k);
return k;
}
int update(int x,int l,int r,int pos,int val)
{
int k = cur++;
tr[k] = tr[x];
if (l == pos && r == pos) {
tr[k].cnt += val;
return k;
}
int mid = (l + r) >> 1;
if (pos <= mid)
tr[k].l = update(tr[x].l, l, mid, pos, val);
else
tr[k].r = update(tr[x].r, mid + 1, r, pos, val);
pushup(k);
return k;
}
int Ask(int l,int r,int x,int v,int kth) {
if (l == r)return l;
int mid = (l + r) >> 1;
int res = tr[tr[v].l].cnt - tr[tr[x].l].cnt;
if (kth <= res)return Ask(l, mid, tr[x].l, tr[v].l, kth);
else return Ask(mid + 1, r, tr[x].r, tr[v].r, kth - res);
}
int b[N];
int sortb[N];
int main()
{
while(~scanf("%d%d",&n,&m))
{
//init();
cur=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
sortb[i]=b[i];
}
sort(sortb+1,sortb+n+1);
int cnt=1;
for(int i =2;i<=n;i++)
{
if(sortb[i]!=sortb[cnt])
sortb[++cnt]=sortb[i];
}
rt[0]=build(1,cnt);
for(int i=1;i<=n;i++)
{
int p=lower_bound(sortb+1,sortb+1+cnt,b[i]) - sortb;
rt[i]=update(rt[i-1],1,cnt,p,1);
}
int l,r,k,z;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&l,&r,&k);
int idx=Ask(1,cnt,rt[l-1],rt[r],k);
printf("%d\n",sortb[idx]);
}
}
return 0;
}
/*
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
*/