zoukankan      html  css  js  c++  java
  • [LOJ107] 维护全序集

    对于 2,3 操作,用权值线段树处理

    对于 4,5 操作,用 std::multiset 处理

    注意 s.upper_boundupper_bound 的区别,后者复杂度爆炸

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    const int M = 10000005;
    
    int a[M], ch[M][2], t1, t2, t3, n = 1e9 + 1, m, ind = 1;
    
    void modify(int p, int l, int r, int pos, int key) {
        a[p] += key;
        if (l < r) {
            if (pos <= (l + r) / 2) {
                if (ch[p][0] == 0)
                    ch[p][0] = ++ind;
                modify(ch[p][0], l, (l + r) / 2, pos, key);
            } else {
                if (ch[p][1] == 0)
                    ch[p][1] = ++ind;
                modify(ch[p][1], (l + r) / 2 + 1, r, pos, key);
            }
        }
    }
    
    int query(int p, int l, int r, int ql, int qr) {
        if (l > qr || r < ql || p == 0)
            return 0;
        if (l >= ql && r <= qr)
            return a[p];
        return query(ch[p][0], l, (l + r) / 2, ql, qr) + query(ch[p][1], (l + r) / 2 + 1, r, ql, qr);
    }
    
    int kth(int p, int l, int r, int k) {
        if (a[p] < k)
            return 0;
        if (l == r)
            return l;
        if (a[ch[p][0]] < k)
            return kth(ch[p][1], (l + r) / 2 + 1, r, k - a[ch[p][0]]);
        return kth(ch[p][0], l, (l + r) / 2, k);
    }
    
    int find(int x) {
        int p = 1;
        int l = 1, r = n;
        while (p && l < r) {
            if (x <= (l + r) / 2)
                r = (l + r) / 2, p = ch[p][0];
            else
                l = (l + r) / 2 + 1, p = ch[p][1];
        }
        return p;
    }
    
    void insert(int x) { modify(1, 1, n, x, 1); }
    
    void remove(int x) { modify(1, 1, n, x, -1); }
    
    int kth(int k) { return kth(1, 1, n, k); }
    
    int getrank(int x) { return query(1, 1, n, 1, x - 1); }
    
    multiset<int> s, u;
    
    signed main() {
        ios::sync_with_stdio(false);
        scanf("%lld", &m);
        while (m--) {
            scanf("%lld%lld", &t1, &t2);
            switch (t1) {
                case 0:
                    insert(t2 + 1);
                    s.insert(t2);
                    u.insert(-t2);
                    break;
                case 1:
                    remove(t2 + 1);
                    s.erase(s.find(t2));
                    u.erase(u.find(-t2));
                    break;
                case 2:
                    printf("%lld
    ", kth(t2) - 1);
                    break;
                case 3:
                    printf("%lld
    ", getrank(t2 + 1));
                    break;
                case 4: {
                    auto tmp1 = u.upper_bound(-t2);
                    if (tmp1 == u.end())
                        puts("-1");
                    else
                        printf("%lld
    ", -*tmp1);
                } break;
                case 5: {
                    auto tmp2 = s.upper_bound(t2);
                    if (tmp2 == s.end())
                        puts("-1");
                    else
                        printf("%lld
    ", *tmp2);
                } break;
            }
        }
    }
    
  • 相关阅读:
    现代程序设计 homework-07
    现代程序设计 homework-05
    现代程序设计 homework-04
    [现代程序设计]homework-03
    [软件工程--个人作业] 敏捷开发读后感
    软件工程 --- Pair Project: Elevator Scheduler [电梯调度算法的实现和测试] [附加题]
    【现代程序设计】加分作业2-《代码大全》第18章表驱动法阅读报告
    【现代程序设计】加分作业1-对Stack的理解
    【现代程序设计】homework-10
    【现代程序设计】homework-09
  • 原文地址:https://www.cnblogs.com/mollnn/p/12531607.html
Copyright © 2011-2022 走看看