您的位置:首页 > 其它

POJ 2104/HDU 2665 区间k大值 函数式线段树

2013-02-18 23:10 489 查看
ORZ主席,这可持久化数据结构真是碉堡了!~

PS:这两个题的读入是不同的。。。

View Code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define N 100010

using namespace std;

int h[N<<5],ls[N<<5],rs[N<<5],sum[N<<5];
int cnt,n,m;
int a
,bh
;

inline int newnode(int s,int l,int r)
{
++cnt;
sum[cnt]=s; ls[cnt]=l; rs[cnt]=r;
return cnt;
}

inline void build(int l,int r,int &rt)
{
rt=newnode(0,0,0);
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,ls[rt]);
build(mid+1,r,rs[rt]);
}

inline void updata(int last,int pos,int l,int r,int &rt)
{
rt=newnode(sum[last]+1,ls[last],rs[last]);
if(l==r) return;
int mid=(l+r)>>1;
if(pos<=mid) updata(ls[last],pos,l,mid,ls[rt]);
else updata(rs[last],pos,mid+1,r,rs[rt]);
}

inline int query(int st,int ed,int l,int r,int k)
{
if(l==r) return l;
int mid=(l+r)>>1;
int tmp=sum[ls[ed]]-sum[ls[st]];
if(k<=tmp) return query(ls[st],ls[ed],l,mid,k);
else return query(rs[st],rs[ed],mid+1,r,k-tmp);
}

inline void read()
{
cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
bh[i]=a[i];
}
}

inline void go()
{
sort(bh+1,bh+1+n);
int num=unique(bh+1,bh+1+n)-bh-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(bh+1,bh+1+num,a[i])-bh;
build(1,num,h[0]);
for(int i=1;i<=n;i++) updata(h[i-1],a[i],1,num,h[i]);
int l,r,k;
while(m--)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",bh[query(h[l-1],h[r],1,num,k)]);
}
}

int main()
{
while(scanf("%d%d",&n,&m)!=EOF) read(),go();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: