poj2124:K-th Number

来源:互联网 发布:pat端口地址转换 编辑:程序博客网 时间:2024/06/05 02:51

传送门
主席树裸题。
按照题意建立主席数
每次二分判断答案大小即可

#include<cstdio>#include<cstdlib>#include<iostream>#include<cmath>#include<cstring>#include<algorithm>#define N 100005using namespace std;int ls[N*20],rs[N*20],sum[N*20];int rt[N],a[N],b[N],n,m,x,y,z,tot;void build(int &nx,int x,int l,int r,int v){    nx=++tot;    sum[nx]=sum[x]+1;    ls[nx]=ls[x];    rs[nx]=rs[x];    if (l==r) return;    int mid=(l+r)/2;    if (v<=mid) build(ls[nx],ls[x],l,mid,v);    else build(rs[nx],rs[x],mid+1,r,v);}int ask(int x,int y,int l,int r,int rk){    if (l==r) return l;    int tmp=sum[ls[y]]-sum[ls[x]],mid=(l+r)/2;    if (rk<=tmp) return ask(ls[x],ls[y],l,mid,rk);    else return ask(rs[x],rs[y],mid+1,r,rk-tmp);}int main(){    scanf("%d%d",&n,&m);    for (int i=1;i<=n;i++)        scanf("%d",&a[i]),b[i]=a[i];    sort(b+1,b+n+1);    for (int i=1;i<=n;i++){        x=lower_bound(b+1,b+n+1,a[i])-b;        build(rt[i],rt[i-1],1,n,x);    }    for (int i=1;i<=m;i++){        scanf("%d%d%d",&x,&y,&z);        printf("%d\n",b[ask(rt[x-1],rt[y],1,n,z)]);    }}
0 1
原创粉丝点击