zoukankan      html  css  js  c++  java
  • 主席树

    省赛主席树模板题和zyn大佬想了两个小时没想出来 太菜了太菜了

    要是我能强到和HJT大神一样能在考场上想出一个主席树一样的东西就好了哈哈哈

    感觉主席树就是一个线段树加前缀和加一个优化

    主要用于求区间第k小的问题

    如果区间是固定的 用线段树或者是归并都好求

    用线段树的话 每个节点就存这个区间有的数的个数 如果要查询的k比节点左子树的权值要小于等于的话

    说明这个区间的左孩子里至少有k个数 那第k小肯定就在左孩子区间里了

    如果要求一个动态的区间【L,R】中的第k小

    我们可以对区间【1,L】和【1,R】建线段树

    因为线段树的节点可以相加减

    所以结果就类似于前缀和 减一下 就可以了

    但是这样的话时间和空间都会爆

    主席树就是发现 每次更改一个节点的值的时候 一棵树上只有一条路径会被更改 也就是logn个节点

    第i棵线段树和第i+1棵 只需要修改logn个节点

    所以每次只创建和上次不同的节点 相同的就用之前的就可以了

    为了节省空间,可以将第 00 棵线段树置为空,每次插入一个新叶子节点时接入一条长度为 O(log n)O(logn)的链。总空间、时间复杂度仍为 O(n log n)O(nlogn)

    查询时构造整棵线段树,需要构造 O(n log n)O(nlogn) 个节点,但每次查询只会用到 O(log n)O(logn) 个节点,直接动态构造这些节点即可。为了方便,可以不显式构造这些节点,而是直接用两棵线段树上的值相减。

    需要注意的是

    主席树需要动态开点

    因为普通的线段树 我们可以算出左右孩子的下标

    但是主席树是变化的 就需要动态开点 每个节点要多存一下左右孩子的下标

    来!上模板!

    struct node{
        int sum, l, r;//l到r之间数的个数 左儿子右儿子编号
    }T[maxn * 40];
    int x, y, k;
    int root[maxn], cnt, a[maxn], n, m;
    
    void update(int l, int r, int &x, int y, int pos)
    {
        T[++cnt] = T[y];
        T[cnt].sum++;
        x = cnt;
        if(l == r) return;
        int mid = (l + r) / 2;
        if(mid >= pos)
            update(l, mid, T[x].l, T[y].l, pos);
        else
            update(mid + 1, r, T[x].r, T[y].r, pos);
    }
    
    int query(int l, int r, int x, int y, int k)
    {
        if(l == r) return l;
        int mid = (l + r) / 2;
        int sum = T[T[y].l].sum - T[T[x].l].sum;
        if(sum >= k) return query(l, mid, T[x].l, T[y].l, k);
        return query(mid +1, r, T[x].r, T[y].r, k - sum);
    }
    
    vector<int>v;
    int getid(int x)
    {
        return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
    }//离散化


  • 相关阅读:
    利用python对新浪微博用户标签进行分词并推荐相关用户
    企业微信公众平台建设指南
    微信5.0:可定制菜单栏、移动支付、公众账号付费订阅
    jquery 控件使用 讲解 连载
    网络那些事
    拒绝访问 无法删除文件的解决方法
    Ubuntu9.10下安装Maya8.5(Finish)
    Ubuntu 9.10 更新软件源列表
    [转载]PHP的Class分页
    PHP与Mysql的连接
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643405.html
Copyright © 2011-2022 走看看