可以整体二分求,当然主席树也可以
#include <cstdio>
#include <algorithm>
#define lowbit(x) ((x)&(-x))
#define N 100010
using namespace std;
const int Inf=1e9;
struct node{
int x,id;
friend bool operator <(node a,node b){
return a.x<b.x;
}
}A[N];
struct que{
int id,x,y,k,cnt;
}q[N],tmp[N];
int n,m,Ans[N],sum[N];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
inline void calc(int l,int r,int ll,int mid){
int L=1,R=n,M;
for(;L<R;){
M=(L+R)>>1;
if(A[M].x>=ll) R=M;
else L=M+1;
}
for(int i=R;i<=n&&A[i].x<=mid;++i)
for(int j=A[i].id;j<=n;j+=lowbit(j))
++sum[j];
for(int i=l;i<=r;++i){
q[i].cnt=0;
for(int j=q[i].y;j;j-=lowbit(j)) q[i].cnt+=sum[j];
for(int j=q[i].x-1;j;j-=lowbit(j)) q[i].cnt-=sum[j];
}
for(int i=R;i<=n&&A[i].x<=mid;++i)
for(int j=A[i].id;j<=n;j+=lowbit(j))
--sum[j];
}
inline void slove(int l,int r,int L,int R){
if(L==R){
for(int i=l;i<=r;++i) Ans[q[i].id]=L;
return;
}
int mid=(L+R)>>1;
calc(l,r,L,mid);
int ta=l,tb=r;
for(int i=l;i<=r;++i)
if(q[i].cnt>=q[i].k) tmp[ta++]=q[i];
else q[i].k-=q[i].cnt,tmp[tb--]=q[i];
for(int i=l;i<=r;++i) q[i]=tmp[i];
if(ta!=l) slove(l,ta-1,L,mid);
if(tb!=r) slove(tb+1,r,mid+1,R);
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;++i) A[A[i].id=i].x=read();
sort(A+1,A+n+1);
for(int i=1;i<=m;++i) q[q[i].id=i].x=read(),q[i].y=read(),q[i].k=read();
slove(1,m,-Inf,Inf);
for(int i=1;i<=m;++i) printf("%d\n",Ans[i]);
return 0;
}
原文:https://www.cnblogs.com/void-f/p/9052916.html