• 【POJ2104/HDU2665】Kth Number-主席树-可持久化线段树


    Problem Kth Number

    Solution

    裸的主席树,模板题。但是求k大的时候需要非常注意,很多容易写错的地方。卡了好久。写到最后还给我来个卡空间。 
    具体做法参见主席树论文《可持久化数据结构研究》。

    AC Code

    #include "cstdio"
    #include "iostream"
    #include "cstring"
    #include "algorithm"
    using namespace std;
    int T,a[100010],root[100010],b[100010],l,r,k,tot;
    struct discre{
        int num,sum;
    }dctz[100010];
    struct tree{
        int lc,rc,sum;
    }tr[100010*21];
    bool cmp(discre a,discre b){
        return a.sum<b.sum;
    }
    void build(int now,int l,int r){
        int mid=(l+r)/2;
        tr[now].sum=0;
        if(l==r){
            return;
        }
        tr[now].lc=++tot;
        build(tot,l,mid);
        tr[now].rc=++tot;
        build(tot,mid+1,r);
    }
    void insert(int last,int sum,int l,int r){
        tr[++tot]=tr[last];
        tr[tot].sum++;
        int x=tot;
        if(l==r){
            return;
        }
        int mid=(l+r)/2;
        if(sum>mid){
            tr[tot].rc=tot+1;
            insert(tr[last].rc,sum,mid+1,r);
        }else{
            tr[tot].lc=tot+1;
            insert(tr[last].lc,sum,l,mid);
        }
    }
    int search(int k,int l,int r,int lx,int rx){
        if(lx==rx){
            return lx;
        }
        int mid=(lx+rx)/2;
        int x=tr[tr[r].lc].sum-tr[tr[l].lc].sum;
        if((x>=k))return search(k,tr[l].lc,tr[r].lc,lx,mid);
        else return search(k-x,tr[l].rc,tr[r].rc,mid+1,rx);
    }
    int main(){
        freopen("chairmantree.in","r",stdin);
        scanf("%d",&T);
        while(T--){
            memset(tr,sizeof(tr),0);
            memset(a,sizeof(a),0);
            memset(dctz,sizeof(dctz),0);
            memset(root,sizeof(root),0);
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                dctz[i].sum=a[i];
                dctz[i].num=i;
            }
            sort(dctz+1,dctz+n+1,cmp);
            for(int i=1;i<=n;i++)a[dctz[i].num]=i,b[i]=dctz[i].sum;
            tot=1;
            root[0]=1;
            tr[1].sum=1;
            build(1,1,n);
            for(int i=1;i<=n;i++){
                root[i]=tot+1;
                insert(root[i-1],a[i],1,n);
            }
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&l,&r,&k);
                int x=search(k,root[l-1],root[r],1,n);
                printf("%d
    ",b[x]);
            }
        }
    }
  • 相关阅读:
    软件工程作业3.28
    毕业论文管理系统建模图
    软件工程建模图作业
    酒店管理系统
    闪屏和功能引导页面代码编写
    Android算法编程代码
    3.28软件工程作业
    毕业论文管理系统
    图书管理系统建模图
    酒店预订系统故事
  • 原文地址:https://www.cnblogs.com/skylynf/p/7140475.html
Copyright © 2020-2023  润新知