代码模板
笛卡尔树
l 和 r 的lca 为区间RMQ
// https://codeforces.com/contest/1748/submission/181116336
std::vector<int> lc(n, -1), rc(n, -1), s;
for (int i = 0; i < n; i++) {
while (!s.empty() && a[i] < a[s.back()]) {
int x = s.back();
rc[x] = lc[i];
lc[i] = x;
s.pop_back();
}
s.push_back(i);
}
while (s.size() > 1) {
int x = s.back();
s.pop_back();
rc[s.back()] = x;
}
std::vector<int> stk;
std::vector<int> lc(n, -1), rc(n, -1);
for (int i = 0; i < n; ++i) {
int last = -1;
while (!stk.empty() && a[stk.back()] > a[i]) {
last = stk.back();
stk.pop_back();
}
lc[i] = last;
if (stk.size()) {
rc[stk.back()] = i;
}
stk.push_back(i);
}
树状数组
#include <bits/stdc++.h>
using i64 = long long;
constexpr int N = 2E5 + 5;
std::vector<int> fen1(N), fen2(N);
int fenl[N], fenr[N];
void add(int *fen, int x, int y) {
for (int i = x + 1; i < N; i += i & -i) {
fen[i - 1] += y;
}
}
int sum(int *fen, int x) {
int res = 0;
for (int i = x; i; i = i & (i - 1)) {
res += fen[i - 1];
}
return res;
}
int rangeSum(int *fen, int l, int r) {
return sum(fen, r) - sum(fen, l);
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++i) {
std::cin >> a[i];
}
for (auto &x : a) {
add(fenr, x, 1);
}
i64 ans0 = 0, ans1 = 0;
for (auto &x : a) {
ans0 += 1LL * rangeSum(fenl, x + 1, N) * rangeSum(fenr, x + 1, N);
ans1 += 1LL * sum(fenl, x) * sum(fenr, x);
add(fenl, x, 1);
add(fenr, x, -1);
}
std::cout << ans0 << " " << ans1 << '\n';
}
线段树
#include <bits/stdc++.h>
using i64 = long long;
constexpr int L = 4E5 + 5;
struct Info {
i64 sum = 0;
i64 act = 1;
i64 tag = 0;
void apply(i64 add) {
sum += add * act;
tag += add;
}
} info[L];
Info operator+(Info a, Info b) {
Info c;
c.sum = a.sum + b.sum;
c.act = a.act + b.act;
return c;
}
void pull(int p) {
info[p] = info[2 * p] + info[2 * p + 1];
}
void push(int p) {
info[2 * p].apply(info[p].tag);
info[2 * p + 1].apply(info[p].tag);
info[p].tag = 0;
}
void rangeApply(int p, int l, int r, int x, int y, i64 t) {
if (y <= l || r <= x) {
return;
}
if (x <= l && r <= y) {
info[p].apply(t);
return;
}
int m = (l + r) / 2;
push(p);
rangeApply(2 * p, l, m, x, y, t);
rangeApply(2 * p + 1, m, r, x, y, t);
pull(p);
}
Info rangeQuery(int p, int l, int r, int x, int y) {
if (y <= l || r <= x) {
return Info();
}
if (x <= l && r <= y) {
return info[p];
}
push(p);
int m = (l + r) / 2;
return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
}
void out(int p, int l, int r) {
if (r - l == 1) {
std::cout << info[p].sum << " ";
return;
}
push(p);
int m = (l + r) / 2;
out(2 * p, l, m);
out(2 * p + 1, m, r);
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, m;
std::cin >> n >> m;
std::vector<Info> a(n);
for (int i = 0; i < n; ++i) {
std::cin >> a[i].sum;
}
// build
[&](this auto &&self, int p, int l, int r) -> void {
if (r - l == 1) {
info[p] = a[l];
return;
}
int m = (l + r) / 2;
self(2 * p, l, m);
self(2 * p + 1, m, r);
pull(p);
} (1, 0, n);
for (int i = 0; i < m; ++i) {
int op, x, y;
std::cin >> op >> x >> y;
--x;
if (op == 1) {
i64 k;
std::cin >> k;
rangeApply(1, 0, n, x, y, {k});
} else {
std::cout << rangeQuery(1, 0, n, x, y).sum << "\n";
}
}
return 0;
}
懒标记线段树
#include <bits/stdc++.h>
using i64 = long long;
constexpr int L = 4E5 + 5;
std::vector<int> len(L);
std::vector<int> cnt(L);
std::vector<int> tag(L);
void apply(int p) {
tag[p] ^= 1;
cnt[p] = len[p] - cnt[p];
}
void push(int p) {
if (tag[p] == 0) {
return;
}
tag[p] = 0;
apply(2 * p);
apply(2 * p + 1);
}
void pull(int p) {
cnt[p] = cnt[2 * p] + cnt[2 * p + 1];
// len[p] = len[2 * p] + len[2 * p + 1];
}
void modify(int p, int l, int r, int x, int y) {
if (r <= x || y <= l) {
return;
}
if (x <= l && r <= y) {
apply(p);
return;
}
push(p);
int m = (l + r) / 2;
modify(2 * p, l, m, x, y);
modify(2 * p + 1, m, r, x, y);
pull(p);
}
int query(int p, int l, int r, int x, int y) {
if (r <= x || y <= l) {
return 0;
}
if (x <= l && r <= y) {
return cnt[p];
}
push(p);
int m = (l + r) / 2;
return query(2 * p, l, m, x, y) + query(2 * p + 1, m, r, x, y);
}
auto out(int p, int l, int r) -> void {
if (r - l == 1) {
std::cout << cnt[p] << ' ';
return;
}
push(p);
int m = (l + r) / 2;
out(2 * p, l, m);
out(2 * p + 1, m, r);
if (p == 1) {
std::cout << std::endl;
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, m;
std::cin >> n >> m;
// build
[&](this auto &&self, int p, int l, int r) -> void {
len[p] = r - l;
if (r - l == 1) {
return;
}
int m = (l + r) / 2;
self(2 * p, l, m);
self(2 * p + 1, m, r);
} (1, 0, n);
for (int i = 0; i < m; ++i) {
int c, a, b;
std::cin >> c >> a >> b;
--a;
if (c == 0) {
modify(1, 0, n, a, b);
} else {
std::cout << query(1, 0, n, a, b) << "\n";
}
}
}

随机存一些代码
浙公网安备 33010602011771号