• 【整体二分】【P3834】 【模板】可持久化线段树 1(主席树)


    Description

    给定一个长度为 (n) 的序列, (m) 次操作静态查询区间第 (k)

    Input

    第一行是 (n,m)

    下一行描述这个序列

    下面 (m) 行描述操作

    Output

    每个查询输出一行一个数代表答案

    Hint

    (1~leq~n,~m~leq~2~ imes~10^5)

    值域为 ([-1e9,~1e9])

    Solution

    考虑整体二分。

    将操作和序列全部离线,混在一起操作,在每层中,如果一个插入操作插入的数大于 mid,则压入右边的vector,否则压入左边的vector,这样即可保证在每一层整个序列的插入操作只被操作 (1) 次。用树状数组维护不大于 mid 的插入点,插入点个数不小于 (k) 的查询压入左侧,否则 (k~-=~ ext{压入点个数}) ,压入右侧即可。

    注意一个区间内没有操作的时候要剪枝,否则复杂度会加上值域。

    总复杂度 (O((n + m)~log^2 m))

    Code

    // luogu-judger-enable-o2
    #include <cstdio>
    #include <vector>
    #include <iostream>
    #ifdef ONLINE_JUDGE
    #define freopen(a, b, c)
    #endif
    
    typedef long long int ll;
    
    namespace IPT {
        const int L = 1000000;
        char buf[L], *front=buf, *end=buf;
        char GetChar() {
            if (front == end) {
                end = buf + fread(front = buf, 1, L, stdin);
                if (front == end) return -1;
            }
            return *(front++);
        }
    }
    
    template <typename T>
    inline void qr(T &x) {
        char ch = IPT::GetChar(), lst = ' ';
        while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
        while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
        if (lst == '-') x = -x;
    }
    
    namespace OPT {
        char buf[120];
    }
    
    template <typename T>
    inline void qw(T x, const char aft, const bool pt) {
        if (x < 0) {x = -x, putchar('-');}
        int top=0;
        do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
        while (top) putchar(OPT::buf[top--]);
        if (pt) putchar(aft);
    }
    
    const int maxn = 200010;
    const int INF = 1000000010;
    
    struct OP {
        int l, r, k, id;
    };
    std::vector<OP> Q;
    
    int n, m;
    int ans[maxn], tree[maxn];
    
    int lowbit(int);
    int query(int);
    void update(int, const int);
    void divide(int, int, std::vector<OP>&);
    
    int main() {
        freopen("1.in", "r", stdin);
        qr(n); qr(m);
        for (int i = 1, x; i <= n; ++i) {
            x = 0; qr(x); Q.push_back({-1, 0, x, i});
        }
        for (int i = 1, a, b, c; i <= m; ++i) {
            a = b = c = 0; qr(a); qr(b); qr(c);
            Q.push_back({a, b, c, i});
        }
        divide(-INF, INF, Q);
        for (int i = 1; i <= m; ++i) qw(ans[i], '
    ', true);
        return 0;
    }
    
    void divide(int l, int r, std::vector<OP> &v) {
        if (!v.size()) return;
        if (l == r) {
            for (auto i : v) if (i.l != -1) ans[i.id] = l;
            return;
        }
        std::vector<OP>ldown, rdown;
        int mid = (l + r) >> 1;
        for (auto i : v) {
            if (i.l == -1) {
                if (i.k <= mid) {
                    update(i.id, 1);
                    ldown.push_back(i);
                } else rdown.push_back(i);
            }
        }
        for (auto i : v) {
            if (i.l != -1) {
                int k = query(i.r) - query(i.l - 1);
                if ((k) >= i.k) ldown.push_back(i);
                else {
                    i.k -= k; rdown.push_back(i);
                }
            }
        }
        for (auto i : ldown) {
            if (i.l == -1) update(i.id, -1);
        }
        divide(l, mid, ldown);
        divide(mid + 1, r, rdown);
    }
    
    inline int lowbit(int x) {return x & -x;}
    
    void update(int x, const int v) {
        while (x <= n) {
            tree[x] += v;
            x += lowbit(x);
        }
    }
    
    int query(int x) {
        int _ret = 0;
        while (x) {
            _ret += tree[x];
            x -= lowbit(x);
        }
        return _ret;
    }
    
  • 相关阅读:
    Android基础知识之拼写检查框架
    Android USB配件模式
    Android基础知识之Manifest中的Intent-filter元素
    如何使Android应用支持多种屏幕分辨率
    优惠券系统设计(系统设计设计篇)
    优惠券系统设计(数据库设计篇)
    优惠券系统设计(产品设计篇)
    java 文件断点续传实现原理
    java sleep和wait的区别的疑惑?
    java中的中断Thread.interrupt()意味着什么?
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/10430542.html
Copyright © 2020-2023  润新知