zoukankan      html  css  js  c++  java
  • 可持久化线段树

    P3834 【模板】可持久化线段树 2(主席树)

    这是个非常经典的主席树入门题——静态区间第 (k) 小。

    对于指定的闭区间 ([l, r]) 查询其区间内的第 (k) 小值.

    代码采用指针形式,区间为左闭右闭。

    const ll M = 2e5 + 3;
    int n, N, m, tot, a[M], b[M];
    
    struct node
    {
        int L, R, cnt;
        node *lc, *rc;
    };
    
    struct node by[M * 21], *pool = by, *root[M];
    
    node *New()
    {
        return ++pool;
    }
    
    void update(node *&now)
    {
        now->cnt = now->lc->cnt + now->rc->cnt;
    }
    
    node *build(int l, int r)
    {
        node *now = New();
        now->L = l;
        now->R = r;
        if (l < r)
        {
            int mid = (l + r) >> 1;
            now->lc = build(l, mid);
            now->rc = build(mid + 1, r);
            update(now);
        }
        else
        {
            now->cnt = 0;
            now->lc = now->rc = NULL;
        }
        return now;
    }
    
    inline bool out(node *&now, int l, int r)
    {
        return (now->R < l) || (r < now->L);
    }
    
    void change(node *pre, node *now, int x)
    {
        *now = *pre;
        if (pre->L == x and pre->R == x)
            now->cnt++;
        else
        {
            if (!out(pre->lc, x, x))
            {
                now->lc = New();
                change(pre->lc, now->lc, x);
                update(now);
            }
            else
            {
                now->rc = New();
                change(pre->rc, now->rc, x);
                update(now);
            }
        }
    }
    
    int check(node *&nowl, node *&nowr, int k)
    {
        if (nowl->L == nowl->R)
            return nowl->L;
        int lcnt = nowr->lc->cnt - nowl->lc->cnt;
        if (lcnt >= k)
            return check(nowl->lc, nowr->lc, k);
        else
            return check(nowl->rc, nowr->rc, k - lcnt);
    }
    
    void Main()
    {
        n = read();
        m = read();
        for (int i = 1; i <= n; ++i)
        {
            a[i] = read();
            b[i] = a[i];
        }
        sort(b + 1, b + n + 1);
        N = unique(b + 1, b + n + 1) - b - 1;
        for (int i = 1; i <= n; ++i)
            a[i] = lower_bound(b + 1, b + N + 1, a[i]) - b;
        root[0] = build(1, N);
        for (int i = 1; i <= n; ++i)
        {
            root[++tot] = New();
            change(root[tot - 1], root[tot], a[i]);
        }
        for (int i = 1; i <= m; ++i)
        {
            int l, r, k;
            l = read(), r = read(), k = read();
            int ans = b[check(root[l - 1], root[r], k)];
            printf("%d
    ", ans);
        }
    }
    
    
  • 相关阅读:
    vSan中见证组件witness详解
    zabbix监控企业esxi虚拟机
    新特性之MAPI over HTTP 配置 MAPI over HTTP
    Exchange Server 产品路线图 及 补丁下载
    人生的第一桶金
    这不是我想要的生活,努力才是王道!
    孤独的灵魂该去何处安家
    如何查看myeclipse是否激活
    Visual Studio 2013如何破解(密钥激活)
    unity破解步骤
  • 原文地址:https://www.cnblogs.com/EdisonBa/p/14969202.html
Copyright © 2011-2022 走看看