主席树。。板子HDU2665

来源:互联网 发布:ubuntu 强制删除用户 编辑:程序博客网 时间:2024/06/11 23:01

//主席树真是。。。。。。简称函数式线段树。。。可以用来代替划分树。。。

#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=100000+10;int a[maxn],b[maxn];int sum[maxn<<5],lson[maxn<<5],rson[maxn<<5];int root[maxn];int tot;void pushdown(int x){    sum[x]=sum[lson[x]]+sum[rson[x]];}int build(int l,int r){    int now=++tot;    if(l==r)    {        sum[now]=0;        lson[now]=0;        rson[now]=0;        return now;    }    int mid=(l+r)>>1;    lson[now]=build(l,mid);    rson[now]=build(mid+1,r);    pushdown(now);    return now;}int update(int rt,int pos,int l,int r){    int now=++tot;    if(l==r)    {        sum[now]=sum[rt]+1;        lson[now]=rson[now]=0;        return now;    }    int m=(l+r)>>1;    if(pos<=m)       lson[now]=update(lson[rt],pos,l,m),rson[now]=rson[rt];    else        rson[now]=update(rson[rt],pos,m+1,r),lson[now]=lson[rt];    pushdown(now);    return now;}int ask(int rt1,int rt2,int k,int l,int r){    if(l==r)        return b[l];    int num=sum[lson[rt2]]-sum[lson[rt1]];    int m=(l+r)>>1;    if(num>=k)        return ask(lson[rt1],lson[rt2],k,l,m);    else        return ask(rson[rt1],rson[rt2],k-num,m+1,r);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n,m;        tot=0;        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);        int d=unique(b+1,b+n+1)-b-1;        root[0]=build(1,d);        for(int i=1;i<=n;i++)        {            int pos=lower_bound(b+1,b+d+1,a[i])-b;            root[i]=update(root[i-1],pos,1,d);        }        for(int i=1;i<=m;i++)        {            int l,r,k;            scanf("%d%d%d",&l,&r,&k);            printf("%d\n",ask(root[l-1],root[r],k,1,d));        }    }    return 0;}


0 0
原创粉丝点击