zoukankan      html  css  js  c++  java
  • P3834 【模板】可持久化线段树 1(主席树)

    传送门

    如标题,主席树模板

    稍微介绍一下主席树..

    主席树是很多个线段树的结合体

    利用了单点修改不会更新太多节点的结论(反正这一题是这样..),后一个线段树借用前面线段树的节点,而对于更新的节点才开一个新的节点存储数据,大大的节省了时间和空间

    (除第一颗树外其他树的构建只要log(n)的时间和空间)

    具体还是看代码吧

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int N=200010;
    int n,m,a[N],b[N],cnt;
    int rt[N<<5],L[N<<5],R[N<<5],sz[N<<5];
    //rt为根节点编号
    //L[i]为节点i的左子树编号,R[i]是节点i的右子树编号
    //sz[i]是以节点i为根的子树的大小
    inline int build(int l,int r) //建立第一颗线段树,不解释
    {
        int root=++cnt;
        if(l==r) return root;
        int mid=l+r>>1;
        L[root]=build(l,mid);
        R[root]=build(mid+1,r);
    }
    inline int add(int l,int r,int k,int pre)//添加新节点
    {
        int root=++cnt; sz[root]=sz[pre]+1;
        //因为每次添加的线段树都比前一个线段树多一个节点
        //所以sz也要比上一个线段树多1
        if(l==r) return root; //如果到边界就返回
        int mid=l+r>>1;
        L[root]=L[pre]; R[root]=R[pre]; //借用前面线段树的节点
        if(k<=mid) L[root]=add(l,mid,k,L[pre]);
        //如果更新的值的位置在左子树就添加新节点到左边,并覆盖L[root]
        else R[root]=add(mid+1,r,k,R[pre]);
        //反之就添加新节点到右边,同样要覆盖
        return root;//返回新节点的编号
    }
    inline int query(int l,int r,int hea,int las,int k)//查询区间第k名
    {
        if(l==r) return l; //如果到边界就返回节点编号
        //找排名的基本操作
        int mid=l+r>>1,x=sz[L[las]]-sz[L[hea]]; 
        if(x>=k) return query(l,mid,L[hea],L[las],k);
        return query(mid+1,r,R[hea],R[las],k-x);
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);//排序
        int len=unique(b+1,b+n+1)-b-1;//去重
        rt[0]=build(1,len);//建树
        for(int i=1;i<=n;i++)
        {
            int t=lower_bound(b+1,b+len+1,a[i])-b;//在b中找<=a[i]的最大位置
            rt[i]=add(1,len,t,rt[i-1]);//加点
        }
        int x,y,z;
        while(m--)
        {
            scanf("%d%d%d",&x,&y,&z);
            printf("%d
    ",b[query(1,len,rt[x-1],rt[y],z)]);
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9536454.html
Copyright © 2011-2022 走看看