zoukankan      html  css  js  c++  java
  • 主席树(可持久化线段树)

    直接看代码似乎更清晰一些

    我们一开始要建一棵空线段树,然后一个一个的添加线段树。加入线段树后会是这样:

    再加入[1,


    至此,裸树就建好了,并且只用了O(nlogn)的空间。
    查询的时候存两个点,一开始为两个区间的根结点,两结点的差比大小,两个点要同时往左/右跳。

    经典问题,区间第k小:

    每个线段树i表示从1~i的所有区间[x,y]中的数的个数;

    答案就是y线段树和x-1线段树的第k小的区间数的个数的差

    #include <bits/stdc++.h>
    using namespace std;
    int n,q,m;
    int a[200010],b[200010];
    int root[20001000];
    int size[20001000];
    int cnt;
    int L[20000100],R[20001000];
    int build(int l,int r)
    {
        int rt=++cnt;
        size[rt]=0;
        if(l==r){        
            return rt;
        }
        int mid=(l+r)/2;
        L[rt]=build(l,mid);
        R[rt]=build(mid+1,r);
        return rt;
    }
    int add(int pre,int l,int r,int goal)
    {
        int rt=++cnt;
        size[rt]=size[pre]+1;
        L[rt]=L[pre];
        R[rt]=R[pre];
        if(l==r){
            return rt;
        }
        int mid=(l+r)/2;
        if(goal<=mid) L[rt]=add(L[pre],l,mid,goal);
        else{
            R[rt]=add(R[pre],mid+1,r,goal);
        }
        return rt;
    }
    int query(int u,int v,int l,int r,int goal)
    {
        if(l==r) return l;
        int tmp=size[L[v]]-size[L[u]];
        int mid=(l+r)/2;
        if(tmp>=goal) return query(L[u],L[v],l,mid,goal);
        else{
            return query(R[u],R[v],mid+1,r,goal-tmp);
        }
        
    }
    int main ()
    {
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        m=unique(b+1,b+1+n)-b-1;
        root[0]=build(1,m);
        for(int i=1;i<=n;i++){
            int tmp=lower_bound(b+1,b+1+m,a[i])-b;
            root[i]=add(root[i-1],1,m,tmp);
        }
        for(int i=1;i<=q;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            int tmp=query(root[x-1],root[y],1,m,z);
            printf("%d
    ",b[tmp]);
        }
    }
  • 相关阅读:
    "bs".endsWith()的使用注意,别用错了
    国外测试专家BLOG地址
    手机测试地址
    校验日期格式{YYYYMM_DD的java代码
    汉字的字节计算情况不同
    AssertThat汇集
    maven常见仓库
    取消冒泡事件
    好看的绿色阴影按钮
    IComparer 继承接口排序 实例 可选择排序
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11271945.html
Copyright © 2011-2022 走看看