数据结构

树状数组

template<typename T> class FenwickTree {
public:
    FenwickTree(int _n): n(_n), c(_n + 1) {}
    FenwickTree(vector<int>& a) {
        n = a.size();
        c.resize(n + 1);
        for (int i = 1; i <= n; ++i) {
            add(i, a[i - 1]);
        }
    }
    void add(int i, int k) {
        while (i <= n) {
            c[i] += k;
            i += lowbit(i);
        }
    }
    T sum(int i) {
        T res = 0;
        while (i) {
            res += c[i];
            i -= lowbit(i);
        }
        return res;
    }
    T sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }
private:
    int n;
    vector<T> c;
    int lowbit(int x) {
        return x & -x;
    }
};

template<typename T> class FenwickTree {
public:
    FenwickTree(int _n): n(_n), a(_n + 1), b(_n + 1) {}
    FenwickTree(vector<int>& c) {
        n = c.size();
        a.resize(n + 1);
        b.resize(n + 1);
        for (int i = 1; i <= n; ++i) {
            int d = (i == 1 ? c[i - 1] : c[i - 1] - c[i - 2]);
            add(a, i, d);
            add(b, i, (i - 1) * d);
        }
    }
    void add(int i, int k) {
        add(i, i, k);
    }
    void add(int l, int r, int k) {
        add(a, l, k);
        add(b, l, k * (l - 1));
        add(a, r + 1, -k);
        add(b, r + 1, -k * r);
    }
    T sum(int l) {
        return sum(l, l);
    }
    T sum(int l, int r) {
        T x = (l - 1) * sum(a, l - 1) - sum(b, l - 1);
        T y = r * sum(a, r) - sum(b, r);
        return y - x;
    }
private:
    int n;
    vector<T> a, b;
    int lowbit(int x) {
        return x & -x;
    }
    void add(vector<T>& a, int i, int k) {
        while (i <= n) {
            a[i] += k;
            i += lowbit(i);
        }
    }
    T sum(vector<T>& a, int i) {
        T res = 0;
        while (i) {
            res += a[i];
            i -= lowbit(i);
        }
        return res;
    }
};

线段树

#define ls(x) (x) << 1
#define rs(x) (x) << 1 | 1
struct Node {
    int l, r, val, add, mul;
    int mid() {
        return (l + r) >> 1;
    }
    int len() {
        return r - l + 1;
    }
    void update(int x, int y) {
        // 乘法
        if (y) {
            val *= y;
            mul *= y;
            add *= y;
        }
        // 加法
        if (x) {
            val += x * len();
            add += x;
        }
    }
} tree[MAXN << 2];
void pushup(int p) {
    tree[p].val = tree[ls(p)].val + tree[rs(p)].val;
}
void pushdown(int p) {
    tree[ls(p)].update(tree[p].add, tree[p].mul);
    tree[rs(p)].update(tree[p].add, tree[p].mul);
    tree[p].add = 0, tree[p].mul = 1;
}
void build(int l, int r, int p) {
    tree[p].l = l, tree[p].r = r;
    tree[p].add = 0, tree[p].mul = 1;
    if (l == r) {

        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, ls(p));
    build(mid + 1, r, rs(p));
    pushup(p);
}
void modify(int l, int r, int add, int mul, int p) {
    if (l <= tree[p].l && tree[p].r <= r) {
        tree[p].update(add, mul);
        return ;
    }
    pushdown(p);
    int mid = tree[p].mid();
    if (l <= mid) modify(l, r, add, mul, ls(p));
    if (r > mid) modify(l, r, add, mul, rs(p));
    pushup(p);
}
int query(int l, int r, int p) {
    if (l <= tree[p].l && tree[p].r <= r) {
        return tree[p].val;
    }
    pushdown(p);
    int mid = tree[p].mid(), res = 0;
    if (l <= mid) res += query(l, r, ls(p));
    if (r > mid) res += query(l, r, rs(p));
    return res;
}

权值线段树

#define ls(x) tree[x].l
#define rs(x) tree[x].r
struct Node {
    int l, r;
    int val, add;
} tree[MAXN * 30]; int idx;
int root, L, R; // 维护的值域
void pushup(int p) {
    tree[p].val = tree[ls(p)].val + tree[rs(p)].val;
}
void insert(int i, int k, int l, int r, int& p) {
    if (!p) p = ++idx;
    if (l == r) {
        tree[p].val += k;
        return ;
    }
    int mid = (l + r) >> 1;
    if (i <= mid) insert(i, k, l, mid, ls(p));
    else insert(i, k, mid + 1, r, rs(p));
    pushup(p);
}
void pushdown(int l, int r, int p) {
    if (tree[p].add) {
        if (!ls(p)) ls(p) = ++idx;
        if (!rs(p)) rs(p) = ++idx;
        int mid = (l + r) >> 1;
        tree[ls(p)].val += tree[p].add * (mid - l + 1);
        tree[rs(p)].val += tree[p].add * (r - mid);
        tree[ls(p)].add += tree[p].add;
        tree[rs(p)].add += tree[p].add;
        tree[p].add = 0;
    }
}
void update(int ql, int qr, int k, int l, int r, int& p) {
    if (!p) p = ++idx;
    if (ql <= l && r <= qr) {
        tree[p].val += k * (r - l + 1);
        tree[p].add += k;
        return ;
    }
    pushdown(l, r, p);
    int mid = (l + r) >> 1;
    if (ql <= mid) update(ql, qr, k, l, mid, ls(p));
    if (qr > mid) update(ql, qr, k, mid + 1, r, rs(p));
    pushup(p);
}
int query(int ql, int qr, int l, int r, int p) {
    if (!p) return 0;
    if (ql <= l && r <= qr) return tree[p].val;
    pushdown(l, r, p);
    int mid = (l + r) >> 1, res = 0;
    if (ql <= mid) res += query(ql, qr, l, mid, ls(p));
    if (qr > mid) res += query(ql, qr, mid + 1, r, rs(p));
    return res;
}

平衡树

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<class T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<class T, class U> using ordered_map = tree<T, U, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<class T, class U> using ordered_multimap = tree<T, U, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

// 使用方法类似set和map, 可以查询第k大

order_of_key(x) // x的排名, 从0开始
find_by_order(x) // 第x大

吉老师线段树

E - Filters

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 2e5 + 5;
const int INF = 0x3f3f3f3f;
int x[MAXN];
#define ls(x) (x) << 1
#define rs(x) (x) << 1 | 1
struct Node {
    int l, r, val, add;
    int max, secmax, cntmax, tagmax;
    int min, secmin, cntmin, tagmin;
    int mid() {
        return (l + r) >> 1;
    }
    int len() {
        return r - l + 1;
    }
    void Add(int x) {
        max += x, min += x;
        val += x * len(), add += x;
        if (secmin != INF) secmin += x;
        if (tagmin != INF) tagmin += x;
        if (secmax != -INF) secmax += x;
        if (tagmax != -INF) tagmax += x;
    }
    void Min(int x) {
        if (max > x) {
            val += (x - max) * cntmax;
            if (secmin == max) secmin = x;
            if (min == max) min = x;
            if (tagmax > x) tagmax = x;
            max = tagmin = x;
        }
    }
    void Max(int x) {
        if (min < x) {
            val += (x - min) * cntmin;
            if (secmax == min) secmax = x;
            if (max == min) max = x;
            if (tagmin < x) tagmin = x;
            min = tagmax = x;
        }
    }
} tree[MAXN << 2];
void pushup(int p) {
    tree[p].val = tree[ls(p)].val + tree[rs(p)].val;
    if (tree[ls(p)].max == tree[rs(p)].max) {
        tree[p].max = tree[ls(p)].max;
        tree[p].cntmax = tree[ls(p)].cntmax + tree[rs(p)].cntmax;
        tree[p].secmax = max(tree[ls(p)].secmax, tree[rs(p)].secmax);
    } else if (tree[ls(p)].max > tree[rs(p)].max) {
        tree[p].max = tree[ls(p)].max;
        tree[p].cntmax = tree[ls(p)].cntmax;
        tree[p].secmax = max(tree[ls(p)].secmax, tree[rs(p)].max);
    } else {
        tree[p].max = tree[rs(p)].max;
        tree[p].cntmax = tree[rs(p)].cntmax;
        tree[p].secmax = max(tree[rs(p)].secmax, tree[ls(p)].max);
    }
    if (tree[ls(p)].min == tree[rs(p)].min) {
        tree[p].min = tree[ls(p)].min;
        tree[p].cntmin = tree[ls(p)].cntmin + tree[rs(p)].cntmin;
        tree[p].secmin = min(tree[ls(p)].secmin, tree[rs(p)].secmin);
    } else if (tree[ls(p)].min < tree[rs(p)].min) {
        tree[p].min = tree[ls(p)].min;
        tree[p].cntmin = tree[ls(p)].cntmin;
        tree[p].secmin = min(tree[ls(p)].secmin, tree[rs(p)].min);
    } else {
        tree[p].min = tree[rs(p)].min;
        tree[p].cntmin = tree[rs(p)].cntmin;
        tree[p].secmin = min(tree[rs(p)].secmin, tree[ls(p)].min);
    }
}
void pushdown(int p) {
    if (tree[p].add) {
        tree[ls(p)].Add(tree[p].add);
        tree[rs(p)].Add(tree[p].add);
        tree[p].add = 0;
    }
    if (tree[p].tagmin != INF) {
        tree[ls(p)].Min(tree[p].tagmin);
        tree[rs(p)].Min(tree[p].tagmin);
        tree[p].tagmin = INF;
    }
    if (tree[p].tagmax != -INF) {
        tree[ls(p)].Max(tree[p].tagmax);
        tree[rs(p)].Max(tree[p].tagmax);
        tree[p].tagmax = -INF;
    }
}
void build(int l, int r, int p) {
    tree[p].l = l, tree[p].r = r;
    tree[p].tagmin = INF, tree[p].tagmax = -INF;
    if (l == r) {
        tree[p].cntmax = tree[p].cntmin = 1;
        tree[p].secmin = INF, tree[p].secmax = -INF;
        tree[p].val = tree[p].max = tree[p].min = x[l];
        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, ls(p));
    build(mid + 1, r, rs(p));
    pushup(p);
}
void add(int l, int r, int k, int p) {
    if (l <= tree[p].l && tree[p].r <= r) {
        tree[p].Add(k);
        return ;
    }
    pushdown(p);
    int mid = tree[p].mid();
    if (l <= mid) add(l, r, k, ls(p));
    if (r > mid) add(l, r, k, rs(p));
    pushup(p);
}
// min(a[l, r], k)
void min(int l, int r, int k, int p) {
    if (tree[p].max <= k) return ;
    if (l <= tree[p].l && tree[p].r <= r && tree[p].secmax < k) {
        tree[p].Min(k);
        return ;
    }
    pushdown(p);
    int mid = tree[p].mid();
    if (l <= mid) min(l, r, k, ls(p));
    if (r > mid) min(l, r, k, rs(p));
    pushup(p);
}
// max(a[l, r], k)
void max(int l, int r, int k, int p) {
    if (tree[p].min >= k) return ;
    if (l <= tree[p].l && tree[p].r <= r && tree[p].secmin > k) {
        tree[p].Max(k);
        return ;
    }
    pushdown(p);
    int mid = tree[p].mid();
    if (l <= mid) max(l, r, k, ls(p));
    if (r > mid) max(l, r, k, rs(p));
    pushup(p);
}
int query(int l, int r, int p) {
    if (l <= tree[p].l && tree[p].r <= r) {
        return tree[p].val;
    }
    pushdown(p);
    int mid = tree[p].mid(), res = 0;
    if (l <= mid) res += query(l, r, ls(p));
    if (r > mid) res += query(l, r, rs(p));
    return res;
}
int32_t main(int argc, char *argv[]) {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int q;
    cin >> q;
    vector<pair<int, int>> ops(q);
    for (auto& [a, t]: ops) {
        cin >> a >> t;
    }
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> x[i];
    }
    build(1, n, 1);
    for (auto [a, t]: ops) {
        if (t == 1) { // x + a
            add(1, n, a, 1);
        }
        else if (t == 2) { // max(x, a)
            max(1, n, a, 1);
        }
        else { // min(x, a)
            min(1, n, a, 1);
        }
    }
    for (int i = 1; i <= n; ++i) {
        cout << query(i, i, 1) << '\n';
    }
    system("pause");
    return 0;
}

扫描线

传入矩阵左下角和右上角坐标,调用\(calc\)函数即可得到交集面积。

struct Line {
    int l, r, h, sgn;
    bool operator <(const Line& p) const {
        return h < p.h;
    }
} a[MAXN];
#define ls(x) x << 1
#define rs(x) x << 1 | 1
struct Node {
    int l, r, val, len;
    int mid() {
        return (l + r) >> 1;
    }
} tree[MAXN << 2];
int x[MAXN];
void pushup(int p) {
    int l = tree[p].l, r = tree[p].r;
    if (tree[p].val) {
        tree[p].len = x[r + 1] - x[l];
    } else {
        tree[p].len = tree[ls(p)].len + tree[rs(p)].len;
    }
}
void build(int l, int r, int p) {
    tree[p].l = l, tree[p].r = r;
    tree[p].len = tree[p].val = 0;
    if (l == r) {
        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, ls(p));
    build(mid + 1, r, rs(p));
}
void update(int ql, int qr, int k, int p) {
    int l = tree[p].l, r = tree[p].r;
    if (ql <= x[l] && x[r + 1] <= qr) {
        tree[p].val += k;
        pushup(p);
        return ;
    }
    int mid = tree[p].mid();
    if (ql <= x[mid]) update(ql, qr, k, ls(p));
    if (qr > x[mid + 1]) update(ql, qr, k, rs(p));
    pushup(p);
}
int calc(vector<tuple<int, int, int, int>>& rec) {
    int n = rec.size();
    for (int i = 1; i <= n; ++i) {
        auto [x1, y1, x2, y2] = rec[i - 1];
        a[i * 2 - 1] = {x1, x2, y1, 1};
        a[i * 2] = {x1, x2, y2, -1};
        x[i * 2 - 1] = x1;
        x[i * 2] = x2;
    }
    n <<= 1;
    sort(a + 1, a + n + 1);
    sort(x + 1, x + n + 1);
    int m = unique(x + 1, x + n + 1) - x - 1;
    build(1, m - 1, 1);
    int res = 0;
    for (int i = 1; i < n; ++i) {
        update(a[i].l, a[i].r, a[i].sgn, 1);
        res += tree[1].len * (a[i + 1].h - a[i].h);
    }
    return res;
}
posted @ 2021-08-12 19:16  stler  阅读(35)  评论(0)    收藏  举报