题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2665
主席树模板题
代码 :
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define sf scanf
#define pf printf
#define totNode maxn * 60
using namespace std;
const int maxn = 100000 + 50;
int ch[totNode][2],SUM[totNode],tot;
void Insert(int prt,int rt,int l,int r,int x,int v){
SUM[rt] = SUM[prt] + v;
while(l < r){
int mid = l + r >> 1;
if(x <= mid){
ch[rt][0] = tot++;
ch[rt][1] = ch[prt][1];
rt = ch[rt][0],prt = ch[prt][0];
r = mid;
}
else{
ch[rt][1] = tot++;
ch[rt][0] = ch[prt][0];
rt = ch[rt][1],prt = ch[prt][1];
l = mid + 1;
}
SUM[rt] = SUM[prt] + v;
}
}
int Query(int rt1,int rt2,int l,int r,int k){
while(l < r){
int mid = l + r >> 1;
if( (SUM[ch[rt2][0]] - SUM[ch[rt1][0]]) >= k){
r = mid;
rt1 = ch[rt1][0],rt2 = ch[rt2][0];
}
else{
k = k - (SUM[ch[rt2][0]] - SUM[ch[rt1][0]]);
l = mid + 1;
rt1 = ch[rt1][1],rt2 = ch[rt2][1];
}
}
return l;
}
int rts[maxn];
struct Node{
int v,id;
}Nodes[maxn];
bool cmp(const Node& a,const Node& b){
return a.v < b.v;
}
int pos[maxn];
int main(){
int n,m;
int T;sf("%d",&T);
while(T--){
sf("%d %d",&n,&m);
tot = 1;
SUM[0] = 0;ch[0][0] = ch[0][1] = 0;
for(int i = 1;i <= n;++i){
sf("%d",&Nodes[i].v);Nodes[i].id = i;
}
sort(Nodes + 1,Nodes + 1 + n,cmp);
for(int i = 1;i <= n;++i){
pos[Nodes[i].id] = i;
}
for(int i = 1;i <= n;++i) Insert(rts[i - 1],rts[i] = tot++,1,n,pos[i],1);
while(m--){
int x,y,k;sf("%d %d %d",&x,&y,&k);
pf("%d\n",Nodes[Query(rts[x - 1],rts[y],1,n,k)].v);
}
}
}