<a target=_blank href="http://poj.org/problem?id=2104" target="_blank"><span style="font-size:24px;">POJ 2104</span></a>
做法好多,主席树,划分树,离线处理(曼哈顿最小生成树?)+BST(Treap or Splay or SBT),貌似分治+BIT也可以,不过懒得搞了。
以后复习模板时用得上。
主席树:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010;
struct Node{
int l,r,w;
}tr[N*20];
int a[N],b[N],rank[N],root[N],sz;
void ins(int &i,int l,int r,int x){
tr[++sz]=tr[i];i=sz;
tr[i].w++;
if(l==r)return;
int m=l+r>>1;
if(x<=m)ins(tr[i].l,l,m,x);
else ins(tr[i].r,m+1,r,x);
}
int query(int i,int j,int l,int r,int k){
if(l==r)return l;
int m=l+r>>1;
int tmp=tr[tr[j].l].w-tr[tr[i].l].w;
if(k<=tmp)return query(tr[i].l,tr[j].l,l,m,k);
else return query(tr[i].r,tr[j].r,m+1,r,k-tmp);
}
inline bool cmp(int i,int j){
return a[i]<a[j];
}
int main(){
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);rank[i]=i;
}
sort(rank+1,rank+1+n,cmp);
for(int i=1;i<=n;i++)b[rank[i]]=i;
for(int i=1;i<=n;i++){
root[i]=root[i-1];
ins(root[i],1,n,b[i]);
}
int x,y,k;
while(m--){
scanf("%d%d%d",&x,&y,&k);
int tmp=query(root[x-1],root[y],1,n,k);
printf("%d\n",a[rank[tmp]]);
}
return 0;
}