您的位置:首页 > 其它

[POJ2104]K-th Number

2015-07-18 22:52 309 查看
原题地址

区间k大裸题,我用的可持久化线段树,树套树过不了OLZ…

代码较挫…

AC code:

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100001;
int n,m,tot=-1;
int a
,hash
;

struct temp
{
int val,rank;
}y
;

struct segtree
{
int l,r,sum;
segtree *Lc,*Rc;
}*root
,t[32*N];

void discrete(int *);
void build(segtree **,int,int);
void insert(int,int);
int get_Kth(int,int,int);

int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
discrete(a);
build(&root[0],1,n);
for(int i=1;i<=n;i++) insert(i,a[i]);
for(int i=1;i<=m;i++){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",hash[get_Kth(l-1,r,k)]);
}

return 0;
}

bool cmp(temp x,temp y)
{
return x.val<y.val;
}

void discrete(int x[])
{
int v=1;
for(int i=1;i<=n;i++){
y[i].rank=i;
y[i].val=x[i];
}
sort(y+1,y+n+1,cmp);
for(int i=1;i<=n;i++){
hash[v]=x[y[i].rank];
x[y[i].rank]=v;
if(y[i+1].val!=y[i].val) v++;
}
}

void build(segtree **p,int L,int R)
{
*p=&t[++tot];
(*p)->l=L;
(*p)->r=R;
(*p)->sum=0;
if(L==R){
(*p)->Lc=(*p)->Rc=NULL;
return ;
}
int mid=(L+R)>>1;
build(&(*p)->Lc,L,mid);
build(&(*p)->Rc,mid+1,R);
}

void insert(int num,int val)
{
segtree **last_p=&root[num-1],**new_p=&root[num];
while(1){
*new_p=&t[++tot];
(*new_p)->l=(*last_p)->l;
(*new_p)->r=(*last_p)->r;
(*new_p)->sum=(*last_p)->sum+1;
if((*new_p)->l==(*new_p)->r) return ;
int mid=((*new_p)->l+(*new_p)->r)>>1;
if(val<=mid){
(*new_p)->Rc=(*last_p)->Rc;
last_p=&(*last_p)->Lc;
new_p=&(*new_p)->Lc;
}
else{
(*new_p)->Lc=(*last_p)->Lc;
last_p=&(*last_p)->Rc;
new_p=&(*new_p)->Rc;
}
}
}

int get_Kth(int Lnum,int Rnum,int K)
{
segtree *Lp=root[Lnum],*Rp=root[Rnum];
while(1){
if(Rp->l==Rp->r) return Rp->l;
if(Rp->Lc->sum-Lp->Lc->sum>=K){
Lp=Lp->Lc;
Rp=Rp->Lc;
}
else{
K-=Rp->Lc->sum-Lp->Lc->sum;
Lp=Lp->Rc;
Rp=Rp->Rc;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: