地址:http://poj.org/problem?id=2104
思路:主席树模板题。。
Code:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int MAX_N=100005;
struct node{
int x;
int id;
bool operator<(const node &p)const{
return (x==p.x)?(id<p.id):(x<p.x);
}
};
struct Tree{
int l,r;
int sum;
};
int n,Q;
node a[MAX_N];
int d[MAX_N];
Tree tree[MAX_N*20]; //主席树空间大小O(nlog(n))
int cnt,root[MAX_N]; //当前线段树,线段树根节点位置
void Init();
void Update(int x,int &rt,int l,int r);
int Query(int L,int R,int k,int l,int r);
int main()
{
scanf("%d%d",&n,&Q);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i].x);
a[i].id=i;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;++i)
d[a[i].id]=i;
Init();
for(int i=1;i<=n;++i)
{
root[i]=root[i-1];
Update(d[i],root[i],1,n);
}
int l,r,k;
while(Q--){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",a[Query(root[l-1],root[r],k,1,n)].x);
}
return 0;
}
void Init()
{
cnt=1;
root[0]=0;
tree[0].l=tree[0].r=tree[0].sum=0;
}
void Update(int x,int &rt,int l,int r)
{
tree[cnt++]=tree[rt]; rt=cnt-1;
++tree[rt].sum;
if(l==r) return;
int mid=(l+r)>>1;
if(x<=mid) Update(x,tree[rt].l,l,mid);
else Update(x,tree[rt].r,mid+1,r);
}
int Query(int L,int R,int k,int l,int r)
{
if(l==r) return l;
int d=tree[tree[R].l].sum-tree[tree[L].l].sum;
int mid=(l+r)>>1,ans;
if(k<=d) ans=Query(tree[L].l,tree[R].l,k,l,mid);
else ans=Query(tree[L].r,tree[R].r,k-d,mid+1,r);
return ans;
}