zoukankan      html  css  js  c++  java
  • 模板

    鉴于水平有限,可能会有问题。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define ls ch[id][0]
    #define rs ch[id][1]
    
    const int INF = 1e9;
    
    const int MAXN = 1000000 + 5;
    int ch[MAXN][2], dat[MAXN];
    
    int val[MAXN];
    int cnt[MAXN];
    int siz[MAXN];
    ll sum[MAXN];
    
    int tot, root;
    
    inline void Init() {
        tot = 0;
        root = 0;
    }
    
    inline int NewNode(int v, int num) {
        int id = ++tot;
        ls = rs = 0;
        dat[id] = rand();
        val[id] = v;
        cnt[id] = num;
        siz[id] = num;
        sum[id] = 1ll * num * v;
        return id;
    }
    
    inline void PushUp(int id) {
        siz[id] = siz[ls] + siz[rs] + cnt[id];
        sum[id] = sum[ls] + sum[rs] + 1ll * cnt[id] * val[id];
    }
    
    inline void Rotate(int &id, int d) {
        int temp = ch[id][d ^ 1];
        ch[id][d ^ 1] = ch[temp][d];
        ch[temp][d] = id;
        id = temp;
        PushUp(ch[id][d]);
        PushUp(id);
    }
    
    //插入num个v
    inline void Insert(int &id, int v, int num) {
        if(!id)
            id = NewNode(v, num);
        else {
            if(v == val[id])
                cnt[id] += num;
            else {
                int d = val[id] > v ? 0 : 1;
                Insert(ch[id][d], v, num);
                if(dat[id] < dat[ch[id][d]])
                    Rotate(id, d ^ 1);
            }
            PushUp(id);
        }
    }
    
    //删除至多num个v
    void Remove(int &id, int v, int num) {
        if(!id)
            return;
        else {
            if(v == val[id]) {
                if(cnt[id] > num) {
                    cnt[id] -= num;
                    PushUp(id);
                } else if(ls || rs) {
                    if(!rs || dat[ls] > dat[rs])
                        Rotate(id, 1), Remove(rs, v, num);
                    else
                        Rotate(id, 0), Remove(ls, v, num);
                    PushUp(id);
                } else
                    id = 0;
            } else {
                val[id] > v ? Remove(ls, v, num) : Remove(rs, v, num);
                PushUp(id);
            }
        }
    }
    
    //查询v的排名,排名定义为<v的数的个数+1。
    int GetRank(int id, int v) {
        int res = 1;
        while(id) {
            if(val[id] > v)
                id = ls;
            else if(val[id] == v) {
                res += siz[ls];
                break;
            } else {
                res += siz[ls] + cnt[id];
                id = rs;
            }
        }
        return res;
    }
    
    //查询排名为rk的数,rk必须是正整数,rk过大返回无穷
    int GetValue(int id, int rk) {
        int res = INF;
        while(id) {
            if(siz[ls] >= rk)
                id = ls;
            else if(siz[ls] + cnt[id] >= rk) {
                res = val[id];
                break;
            } else {
                rk -= siz[ls] + cnt[id];
                id = rs;
            }
        }
        return res;
    }
    
    //查询v的前驱的值(<v的第一个节点的值),不存在前驱返回负无穷
    int GetPrev(int id, int v) {
        int res = -INF;
        while(id) {
            if(val[id] < v)
                res = val[id], id = rs;
            else
                id = ls;
        }
        return res;
    }
    
    //查询v的后继的值(>v的第一个节点的值),不存在后继返回无穷
    int GetNext(int id, int v) {
        int res = INF;
        while(id) {
            if(val[id] > v)
                res = val[id], id = ls;
            else
                id = rs;
        }
        return res;
    }
    
    //查询小于等于v的数的和
    ll GetSumValue(int id, int v) {
        ll res = 0;
        while(id) {
            if(val[id] > v)
                id = ls;
            else if(val[id] == v) {
                res += sum[ls] + 1ll * cnt[id] * val[id];
                break;
            } else {
                res += sum[ls] + 1ll * cnt[id] * val[id];
                id = rs;
            }
        }
        return res;
    }
    
    //查询前rk个数的和,rk必须是正整数
    ll GetSumRank(int id, int rk) {
        ll res = 0;
        while(id) {
            if(siz[ls] >= rk)
                id = ls;
            else if(siz[ls] + cnt[id] >= rk) {
                res += sum[ls] + 1ll * (rk - siz[ls]) * val[id];
                break;
            } else {
                res += sum[ls] + 1ll * cnt[id] * val[id];
                rk -= siz[ls] + cnt[id];
                id = rs;
            }
        }
        return res;
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        Init();
        int ops;
        scanf("%d", &ops);
        for(int i = 1; i <= ops; i++) {
            int op, x;
            scanf("%d%d", &op, &x);
            if(op == 1)
                Insert(root, x, 1);
            else if(op == 2)
                Remove(root, x, 1);
            else if(op == 3)
                printf("%d
    ", GetRank(root, x));
            else if(op == 4)
                printf("%d
    ", GetValue(root, x));
            else if(op == 5)
                printf("%d
    ", GetPrev(root, x));
            else if(op == 6)
                printf("%d
    ", GetNext(root, x));
            else if(op == 7)
                printf("%lld
    ", GetSumRank(root, x));
            else if(op == 8)
                printf("%lld
    ", GetSumValue(root, x));
        }
        return 0;
    }
    
  • 相关阅读:
    maven项目中各文件都没有报错,但是项目名称有红叉
    executeFind()方法和execute()方法区别
    数据库查询
    getHibernateTemplate出现的所有find方法的总结
    HQL和SQL的区别
    Java创建对象的方式
    xml中的<![CDATA[]]>和转义字符
    DWRUtil.addOptions
    dwr
    response.setHeader("Cache-Control","no-cache");的作用
  • 原文地址:https://www.cnblogs.com/Inko/p/11403359.html
Copyright © 2011-2022 走看看