标签:space div += == lse highlight uniq name else
//本模板是离散后对权值建树
#include<bits/stdc++.h>
#define mid (l+r>>1)
using namespace std;
const int N=2e5+10;
struct TR
{
int sum,lo,ro;
}tr[N<<5];
int tr_cnt;//之后需要初始化=0
int n,m,q,arr[N],brr[N],rt[N];//m是权值的数量
void build(int &o,int l=1,int r=m)
{
o=++tr_cnt;
//tr[o].sum=0;
if(l==r)return;
build(tr[o].lo,l,mid);
build(tr[o].ro,mid+1,r);
}
void update(int p,int v,int pre,int &o,int l=1,int r=m)
{
o=++tr_cnt;
tr[o]=tr[pre];
tr[o].sum+=v;//都是+1
if(l==r)return;
if(p<=mid)update(p,v,tr[pre].lo,tr[o].lo,l,mid);
else update(p,v,tr[pre].ro,tr[o].ro,mid+1,r);
}
//u和v是两个线段树的根,相减后的线段树求第k个的下标位置
int query(int k,int u,int v,int l=1,int r=m)
{
if(l==r)return l;
int tmp=tr[tr[v].lo].sum-tr[tr[u].lo].sum;
if(tmp>=k)return query(k,tr[u].lo,tr[v].lo,l,mid);
else return query(k-tmp,tr[u].ro,tr[v].ro,mid+1,r);
}
int main()
{
int n,q;scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%d",arr+i),brr[i]=arr[i];
sort(brr+1,brr+1+n);
m=unique(brr+1,brr+1+n)-brr-1;
build(rt[0]);
for(int i=1;i<=n;i++)
{
int p=lower_bound(brr+1,brr+1+m,arr[i])-brr;
update(p,1,rt[i-1],rt[i]);
}
while(q--)
{
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
printf("%d\n",brr[query(k,rt[u-1],rt[v])]);
}
return 0;
}
标签:space div += == lse highlight uniq name else
原文地址:https://www.cnblogs.com/LH2000/p/14659789.html