题目链接
题意: 查询区间第
k
k
k 小
题解: 主席树的模板题
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<algorithm>
#include<cstdio>
#include<list>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define mid (l+r)/2
#define lowbit(a) ((a)&-(a))
const int mod = 1e9+7;
using namespace std;
inline int read(){
char c=getchar();int x=0,s=1;
while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*s;
}
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
const int maxn = 1e3+10;
struct node{
int l,r;
int sum;
}seg[N<<5];
int cnt;
int root[N],a[N],lsh[N],n,m,q;
int get_id(int x){
return lower_bound(lsh+1,lsh+1+m,x)-lsh;
}
int build(int l,int r){
int rt=++cnt;
if(l<r) seg[rt]={build(l,mid), build(mid+1,r), 0};
return rt;
}
int update(int pre,int l,int r,int val){
int rt=++cnt;
seg[rt]={seg[pre].l, seg[pre].r, seg[pre].sum+1};
if(l<r){
if(val<=mid) seg[rt].l=update(seg[pre].l,l,mid,val);
else seg[rt].r=update(seg[pre].r,mid+1,r,val);
}
return rt;
}
int query(int u,int v,int l,int r,int k){
if(l>=r)return l;
int ans=seg[seg[v].l].sum-seg[seg[u].l].sum;
if(ans>=k) return query(seg[u].l,seg[v].l,l,mid,k);
else return query(seg[u].r,seg[v].r,mid+1,r,k-ans);
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i],lsh[i]=a[i];
sort(lsh+1,lsh+1+n); m=unique(lsh+1,lsh+1+n)-lsh-1;
root[0]=build(1,m);
for(int i=1;i<=n;i++)
root[i]=update(root[i-1],1,m,get_id(a[i]));
while(q--){
int l,r,k; cin>>l>>r>>k;
int res=query(root[l-1],root[r],1,m,k);
cout<<lsh[res]<<endl;
}
}
|