树状数组模板

单点修改,区间查询/区间修改,单点查询

template<typename T>
struct BIT {
    int n;
    vector<T> w;

    BIT() {}
    BIT(int n) {
        this->n = n;
        w.resize(n + 1);
    }
    void update(int x, int k) {
        for (; x <= n; x += x & -x) {
            w[x] += k;
        }
    }
    void update(int x, int y, int k) {//区间修改存入差分,单点查询前缀和
        update(x, k), update(y, -k);
    }
    T ask(int x) {
        T ans = 0;
        for (; x; x -= x & -x) {
            ans += w[x];
        }
        return ans;
    }
    T ask(int x, int y) {
        return ask(y) - ask(x - 1);
    }
    T kth(int k) { //查找第k小的值
        T ans = 0;
        for (int i = __lg(n); i >= 0; i--) {
            int val = ans + (1 << i);
            if (val < n && w[val] < k) {
                k -= w[val];
                ans = val;
            }
        }
        return ans + 1;
    }
    T get(auto x) { //获取逆序对数量
        this->n = x.size() - 1;
        w.resize(n + 1);

        vector<pair<int, int>> a;
        for (int i = 1; i <= n; i++) {
            a.emplace_back(x[i], i);
        }
        sort(a.begin(), a.end());

        T ans = 0;
        for (auto [val, idx] : a) {
            ans += ask(idx + 1, n);
            update(idx, 1);
        }
        return ans;
    }
};
posted @ 2023-12-26 08:58  Ke_scholar  阅读(24)  评论(1编辑  收藏  举报