主席树——求静态区间第k大

时间:2023-03-09 02:36:01
主席树——求静态区间第k大

例题:poj2104 http://poj.org/problem?id=2104

讲解,推荐博客:http://blog.sina.com.cn/s/blog_6022c4720102w03t.html

http://seter.is-programmer.com/posts/31907.html

http://www.cnblogs.com/shenben/p/5598371.html

数组版:

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=;
int l_child[N*],r_child[N*],sum[N*];
int n,m,a[N],hash[N],cnt,root[N];
int x,y,k;
void discrete()
{
sort(hash+,hash+n+);
cnt=unique(hash+,hash+n+)-(hash+);
for(int i=;i<=n;i++) a[i]=lower_bound(hash+,hash+cnt+,a[i])-hash;
}
int init()
{
int x=,f=;char c=getchar();
while(c<''||c>'') {if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int query(int x,int y,int l,int r,int k)
{
if(l==r) return l;
int mid=l+r>>,tmp=sum[l_child[y]]-sum[l_child[x]];
if(tmp>=k) return query(l_child[x],l_child[y],l,mid,k);
else return query(r_child[x],r_child[y],mid+,r,k-tmp);
}
int tot=;
void build(int x,int &y,int l,int r,int v)
{
sum[y=++tot]=sum[x]+;
if(l==r) return;
int mid=l+r>>;
if(v<=mid)
{
r_child[y]=r_child[x];
build(l_child[x],l_child[y],l,mid,v);
}
else
{
l_child[y]=l_child[x];
build(r_child[x],r_child[y],mid+,r,v);
}
}
int main()
{
n=init();m=init();
for(int i=;i<=n;i++) a[i]=init(),hash[i]=a[i];
discrete();
//for(int i=1;i<=n;i++) printf("%d ",a[i]);
for(int i=;i<=n;i++) build(root[i-],root[i],,cnt,a[i]);
for(int i=;i<=m;i++)
{
x=init();y=init();k=init();
printf("%d\n",hash[query(root[x-],root[y],,cnt,k)]);
}
}

指针版:TLE

#include<cstdio>
#include<algorithm>
#define N 100001
using namespace std;
int n,m,a[N],hash[N];
int tot,cnt;
struct node
{
node * l,* r;
int sum;
};
node * root[N];
void discrete()
{
sort(a+,a+n+);
tot=unique(a+,a+n+)-(a+);
for(int i=;i<=n;i++) hash[i]=lower_bound(a+,a+n+,hash[i])-a;
}
inline node * build(node * pre,int l,int r,int w)
{
node *neww=new node();
//node * neww=(node *)malloc(sizeof(node));
neww->sum=pre->sum+;
if(l==r) return neww;
int mid=l+r>>;
if(w<=mid)
{
neww->r=pre->r;
neww->l=build(pre->l,l,mid,w);
}
else
{
neww->l=pre->l;
neww->r=build(pre->r,mid+,r,w);
}
return neww;
}
inline int query(node * x,node * y,int k,int l,int r)
{
if(l==r) return l;
int mid=l+r>>,tmp=y->l->sum-x->l->sum;
if(k<=tmp) return query(x->l,y->l,k,l,mid);
else return query(x->r,y->r,k-tmp,mid+,r);
}
node * null(int ll,int rr)
{
node *neww=new node();
//node * neww=(node *)malloc(sizeof(node));
neww->l=neww->r=NULL;
neww->sum=;
if(ll==rr) return neww;
int mid=ll+rr>>;
neww->l=null(ll,mid);
neww->r=null(mid+,rr);
return neww;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) {scanf("%d",&a[i]);hash[i]=a[i];}
discrete();
root[]=null(,n);
for(int i=;i<=n;i++) root[i]=build(root[i-],,n,hash[i]);
int x,y,k;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&k);
printf("%d\n",a[query(root[x-],root[y],k,,n)]);
}
}