数据结构
树状数组
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大
吉老师线段树
#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;
}

浙公网安备 33010602011771号