主席树模板
主要用来查询区间第k小
insert操作
int insert(int o, int x)
{
int now=++len,root,l=1,r=m,mid;
root=now; s(now)=s(o)+1;
while(l < r)
{
mid=(l+r)/2;
if(x<=mid){
l(now)=++len; r(now)=r(o);
o=l(o); now=len; r=mid;
} else {
r(now)=++len; l(now)=l(o);
o=r(o); now=len; l=mid+1;
}
s(now)=s(o)+1;
}
return root;
}
查询操作
int query(int L, int R, int k)
{
int l=1, r=m, mid;
while(l<r)
{
mid=(l+r)/2;
if(k<=s(l(R))-s(l(L))){
r=mid; R=l(R); L=l(L);
} else {
l=mid+1; k-=s(l(R))-s(l(L));
R=r(R); L=r(L);
}
}
return l;
}
模板题
NEERC 2004 K小数
http://cogs.pro:8080/cogs/problem/problem.php?pid=1534
完整模板
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define File(x) "kthnumber."#x
#define For(i,s,e) for(int i=(s); i<=(e); i++)
#define Rep(i,s,e) for(int i=(s); i>=(e); i--)
using namespace std;
const int N=100000*30+10;
struct HJT
{
int l,r,size;
#define l(x) T[x].l
#define r(x) T[x].r
#define s(x) T[x].size
}T[N];
int a[N],to[N],h[N],m,n,Q,len;
void read(int &x)
{
char ch; int s=1;
while(ch=getchar(),ch>'9' || ch<'0') if(ch=='-') s=-1;
x=ch-'0';
while(ch=getchar(),ch>='0' && ch<='9') x=x*10+ch-'0';
x*=s;
}
void init()
{
memcpy(to, a, sizeof(a));
sort(to+1,to+1+n);
m=unique(to+1,to+1+n)-to-1;
}
int hash(int x)
{
return lower_bound(to+1, to+1+m, x)-to;
}
int build(int l, int r)
{
int o=++len, mid((l+r)/2);
s(o)=0;
if(l!=r)
{
l(o)=build(l,mid); r(o)=build(mid+1,r);
}
return o;
}
int insert(int o, int x)
{
int now=++len,root,l=1,r=m,mid;
root=now; s(now)=s(o)+1;
while(l<r)
{
mid=(l+r)/2;
if(x<=mid){
l(now)=++len; r(now)=r(o);
o=l(o); now=len; r=mid;
} else {
r(now)=++len; l(now)=l(o);
o=r(o); now=len; l=mid+1;
}
s(now)=s(o)+1;
}
return root;
}
int query(int L, int R, int k)
{
int l=1, r=m, mid;
while(l<r)
{
mid=(l+r)/2;
if(k<=s(l(R))-s(l(L))){
r=mid; R=l(R); L=l(L);
} else {
l=mid+1; k-=s(l(R))-s(l(L));
R=r(R); L=r(L);
}
}
return l;
}
int main()
{
freopen(File(in),"r",stdin);
freopen(File(out),"w",stdout);
// ios::sync_with_stdio(false);
read(n); read(Q);
For(i,1,n) read(a[i]);
init();
h[0]=build(1,m);
For(i,1,n) h[i]=insert(h[i-1],hash(a[i]));
while(Q--)
{
int l,r,k;
read(l); read(r); read(k);
printf("%d\n",to[query(h[l-1],h[r],k)]);
}
return 0;
}