单点修改&区间求和
class FenwickTree {
private:
int n, tree[MAXN];
inline int lowbit(int x) {
return x & -x;
}
public:
inline FenwickTree(int _n) {
n = _n;
}
inline void update(int i, int k) {
for ( ; i <= n; i += lowbit(i)) {
tree[i] += k;
}
}
inline int query(int i) {
int res = 0;
for ( ; i; i -= lowbit(i)) {
res += tree[i];
}
return res;
}
};
区间加&区间求和
class FenwickTree {
private:
int n, tree1[MAXN], tree2[MAXN];
inline int lowbit(int x) {
return x & -x;
}
inline void update(int tree[], int i, int k) {
for ( ; i <= n; i += lowbit(i)) {
tree[i] += k;
}
}
inline int sum(int tree[], int i) {
int res = 0;
for ( ; i; i -= lowbit(i)) {
res += tree[i];
}
return res;
}
public:
inline FenwickTree(int _n) {
n = _n;
memset(tree1, 0, sizeof(tree1));
memset(tree2, 0, sizeof(tree2));
}
inline void build(int a[]) {
for (int i = 1; i <= n; ++i) {
int diff = a[i] - a[i - 1];
update(tree1, i, diff);
update(tree2, i, (i - 1) * diff);
}
}
inline void update(int l, int r, int k) {
update(tree1, l, k);
update(tree2, l, k * (l - 1));
update(tree1, r + 1, -k);
update(tree2, r + 1, -k * r);
}
inline int query(int l, int r) {
int x = (l - 1) * sum(tree1, l - 1) - sum(tree2, l - 1);
int y = r * sum(tree1, r) - sum(tree2, r);
return y - x;
}
};
线段树
区间加
#define ls(x) (x) << 1
#define rs(x) (x) << 1 | 1
struct SegmentTreeNode {
int l, r;
int val;
int add;
int mid() {
return (l + r) >> 1;
}
int len() {
return r - l + 1;
}
}tree[MAXN << 2];
void pushup(int p) {
tree[p].val = tree[ls(p)].val + tree[rs(p)].val;
}
void pushdown(int p) {
if (tree[p].add) {
tree[ls(p)].val += tree[p].add * tree[ls(p)].len();
tree[rs(p)].val += tree[p].add * tree[rs(p)].len();
tree[ls(p)].add += tree[p].add;
tree[rs(p)].add += tree[p].add;
tree[p].add = 0;
}
}
void build(int l, int r, int p) {
tree[p].l = l, tree[p].r = r;
if (l == r) {
return ;
}
int mid = (l + r) >> 1;
build(l, mid, ls(p));
build(mid + 1, r, rs(p));
pushup(p);
}
void update(int l, int r, int val, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].val += val * tree[p].len();
tree[p].add += val;
return ;
}
pushdown(p);
int mid = tree[p].mid();
if (l <= mid) update(l, r, val, ls(p));
if (r > mid) update(l, r, val, 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) (x) << 1
#define rs(x) (x) << 1 | 1
struct SegmentTreeNode {
int l, r;
int val;
int add, mul;
int mid() {
return (l + r) >> 1;
}
int len() {
return r - l + 1;
}
}tree[MAXN << 2];
void pushup(int p) {
tree[p].val = (tree[ls(p)].val + tree[rs(p)].val) % MOD;
}
void pushdown(int p) {
if (tree[p].add || tree[p].mul != 1) {
tree[ls(p)].val = (tree[ls(p)].val * tree[p].mul + tree[p].add * tree[ls(p)].len()) % MOD;
tree[rs(p)].val = (tree[rs(p)].val * tree[p].mul + tree[p].add * tree[rs(p)].len()) % MOD;
tree[ls(p)].mul = (tree[ls(p)].mul * tree[p].mul) % MOD;
tree[rs(p)].mul = (tree[rs(p)].mul * tree[p].mul) % MOD;
tree[ls(p)].add = (tree[ls(p)].add * tree[p].mul + tree[p].add) % MOD;
tree[rs(p)].add = (tree[rs(p)].add * tree[p].mul + tree[p].add) % MOD;
tree[p].add = 0;
tree[p].mul = 1;
}
}
void build(int l, int r, int int p) {
tree[p].l = l, tree[p].r = r;
if (l == r) {
return ;
}
int mid = l + r >> 1;
build(l, mid, a, ls(p));
build(mid + 1, r, a, rs(p));
pushup(p);
}
void rangedd(int l, int r, int k, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].add = (tree[p].add + k) % MOD;
tree[p].val = (tree[p].val + k * tree[p].len()) % MOD;
return ;
}
pushdown(p);
int mid = tree[p].mid();
if (l <= mid) rangeAdd(l, r, k, ls(p));
if (r > mid) rangeAdd(l, r, k, rs(p));
pushup(p);
}
void rangeMul(int l, int r, int k, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].add = (tree[p].add * k) % MOD;
tree[p].mul = (tree[p].mul * k) % MOD;
tree[p].val = (tree[p].val * k) % MOD;
return ;
}
pushdown(p);
int mid = tree[p].mid();
if (l <= mid) rangeMul(l, r, k, ls(p));
if (r > mid) rangeMul(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 = (res + query(l, r, ls(p))) % MOD;
if (r > mid) res = (res + query(l, r, rs(p))) % MOD;
return res;
}
区间覆盖&区间加&区间最值
#define ls(x) (x) << 1
#define rs(x) (x) << 1 | 1
struct SegmentTreeNode {
int l, r;
int max;
int add, cov;
inline int mid() {
return (l + r) >> 1;
}
inline int len() {
return r - l + 1;
}
}tree[MAXN << 2];
void pushup(int p) {
tree[p].max = max(tree[ls(p)].max, tree[rs(p)].max);
}
void pushdown(int p) {
if (tree[p].cov) {
tree[ls(p)].max = tree[rs(p)].max = tree[p].cov;
tree[ls(p)].cov = tree[rs(p)].cov = tree[p].cov;
tree[ls(p)].add = tree[rs(p)].add = 0;
tree[p].cov = 0;
}
if (tree[p].add) {
tree[ls(p)].max += tree[p].add;
tree[rs(p)].max += tree[p].add;
tree[ls(p)].add += tree[p].add;
tree[rs(p)].add += tree[p].add;
tree[p].add = 0;
}
}
void build(int l, int r, int p) {
tree[p].l = l, tree[p].r = r;
if (l == r) {
return ;
}
int mid = (l + r) >> 1;
build(l, mid, ls(p));
build(mid + 1, r, rs(p));
pushup(p);
}
void cover(int l, int r, int k, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].max = k;
tree[p].cov = k;
tree[p].add = 0;
return ;
}
pushdown(p);
int mid = tree[p].mid();
if (l <= mid) cover(l, r, k, ls(p));
if (r > mid) cover(l, r, k, rs(p));
pushup(p);
}
void update(int l, int r, int k, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].max += k;
tree[p].add += k;
return ;
}
pushdown(p);
int mid = tree[p].mid();
if (l <= mid) update(l, r, k, ls(p));
if (r > mid) update(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].max;
}
pushdown(p);
int mid = tree[p].mid(), res = 0;
if (l <= mid) res = max(res, query(l, r, ls(p)));
if (r > mid) res = max(res, query(l, r, rs(p)));
return res;
}
单点修改&区间最值
#define ls(x) (x) << 1
#define rs(x) (x) << 1 | 1
struct SegmentTreeNode {
int l, r;
int min, max;
int mid() {
return (l + r) >> 1;
}
}tree[MAXN << 2];
void pushup(int p) {
tree[p].min = min(tree[ls(p)].min, tree[rs(p)].min);
tree[p].max = max(tree[ls(p)].max, tree[rs(p)].max);
}
void build(int l, int r, int p) {
tree[p].l = l, tree[p].r = r;
if (l == r) {
tree[p].min = a[l];
tree[p].max = a[l];
return ;
}
int mid = (l + r) >> 1;
build(l, mid, ls(p));
build(mid + 1, r, rs(p));
pushup(p);
}
void update(int i, int k, int p) {
if (tree[p].l == tree[p].r) {
tree[p].min = k;
tree[p].max = k;
return ;
}
int mid = tree[p].mid();
if (i <= mid) update(i, k, ls(p));
if (i > mid) update(i, k, rs(p));
pushup(p);
}
int queryMin(int l, int r, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
return tree[p].min;
}
int mid = tree[p].mid(), res = INF;
if (l <= mid) res = min(res, queryMin(l, r, ls(p)));
if (r > mid) res = min(res, queryMin(l, r, rs(p)));
return res;
}
int queryMax(int l, int r, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
return tree[p].max;
}
int mid = tree[p].mid(), res = -INF;
if (l <= mid) res = max(res, queryMax(l, r, ls(p)));
if (r > mid) res = max(res, queryMax(l, r, rs(p)));
return res;
}
权值线段树
区间加&区间求和
#define ls(x) tree[x].l
#define rs(x) tree[x].r
struct SegmentTreeNode {
int l, r;
int val, add;
}tree[MAXN * 30]; int idx;
class SegmentTree {
private:
int root;
int left, right; // 维护的值域
inline void pushup(int p) {
tree[p].val = tree[ls(p)].val + tree[rs(p)].val;
}
inline 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);
}
inline 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;
}
}
inline 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);
}
inline 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;
}
public:
inline SegmentTree(int l, int r) {
idx = root = 0;
left = l, right = r;
}
inline void insert(int p, int x) {
insert(p, x, left, right, root);
}
inline void update(int l, int r, int k) {
return update(l, r, k, left, right, root);
}
inline int query(int l, int r) {
return query(l, r, left, right, root);
}
};
单点修改&区间最值
#define ls(x) tree[x].l
#define rs(x) tree[x].r
struct SegmentTreeNode {
int l, r;
int min, max;
}tree[MAXN * 30]; int idx;
class SegmentTree {
private:
int root;
int left, right; // 维护的值域
inline void pushup(int p) {
tree[p].min = min(tree[ls(p)].min, tree[rs(p)].min);
tree[p].max = max(tree[ls(p)].max, tree[rs(p)].max);
}
inline void insert(int i, int k, int l, int r, int &p) {
if (!p) p = ++idx;
if (l == r) {
tree[p].min = k;
tree[p].max = 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);
}
inline int queryMin(int ql, int qr, int l, int r, int p) {
if (!p) return INF;
if (ql <= l && r <= qr) return tree[p].min;
int mid = (l + r) >> 1, res = INF;
if (ql <= mid) res = min(res, queryMin(ql, qr, l, mid, ls(p)));
if (qr > mid) res = min(res, queryMin(ql, qr, mid + 1, r, rs(p)));
return res;
}
inline int queryMax(int ql, int qr, int l, int r, int p) {
if (!p) return -INF;
if (ql <= l && r <= qr) return tree[p].max;
int mid = (l + r) >> 1, res = -INF;
if (ql <= mid) res = max(res, queryMax(ql, qr, l, mid, ls(p)));
if (qr > mid) res = max(res, queryMax(ql, qr, mid + 1, r, rs(p)));
return res;
}
public:
inline SegmentTree(int l, int r) {
idx = root = 0;
left = l, right = r;
}
inline void insert(int p, int x) {
insert(p, x, left, right, root);
}
inline int queryMin(int l, int r) {
return queryMin(l, r, left, right, root);
}
inline int queryMax(int l, int r) {
return queryMax(l, r, left, right, root);
}
};
吉老师线段树
Gorgeous Sequence - HDU 5306 - Virtual Judge (vjudge.net)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e6 + 5;
int a[MAXN];
#define ls(x) (x) << 1
#define rs(x) (x) << 1 | 1
struct SegmentTreeNode {
int l, r;
int val, max, cnt, secmax;
int tag;
int mid() {
return (l + r) >> 1;
}
}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].cnt = tree[ls(p)].cnt + tree[rs(p)].cnt;
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].cnt = tree[ls(p)].cnt;
tree[p].secmax = max(tree[ls(p)].secmax, tree[rs(p)].max);
}
else {
tree[p].max = tree[rs(p)].max;
tree[p].cnt = tree[rs(p)].cnt;
tree[p].secmax = max(tree[rs(p)].secmax, tree[ls(p)].max);
}
}
void pushdown(int p) {
if (tree[p].tag == -1) return ;
if (tree[ls(p)].max > tree[p].tag) {
tree[ls(p)].val -= (tree[ls(p)].max - tree[p].tag) * tree[ls(p)].cnt;
tree[ls(p)].max = tree[ls(p)].tag = tree[p].tag;
}
if (tree[rs(p)].max > tree[p].tag) {
tree[rs(p)].val -= (tree[rs(p)].max - tree[p].tag) * tree[rs(p)].cnt;
tree[rs(p)].max = tree[rs(p)].tag = tree[p].tag;
}
tree[p].tag = -1;
}
void build(int l, int r, int p) {
tree[p].l = l, tree[p].r = r;
tree[p].tag = -1;
if (l == r) {
tree[p].cnt = 1;
tree[p].secmax = -1;
tree[p].val = tree[p].max = a[l];
return ;
}
int mid = (l + r) >> 1;
build(l, mid, ls(p));
build(mid + 1, r, rs(p));
pushup(p);
}
void update(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].val -= (tree[p].max - k) * tree[p].cnt;
tree[p].max = tree[p].tag = k;
return ;
}
pushdown(p);
int mid = tree[p].mid();
if (l <= mid) update(l, r, k, ls(p));
if (r > mid) update(l, r, k, rs(p));
pushup(p);
}
int queryMax(int l, int r, int p) {
if (l <= tree[p].l && tree[p].r <= r) {
return tree[p].max;
}
pushdown(p);
int mid = tree[p].mid(), res = 0;
if (l <= mid) res = max(res, queryMax(l, r, ls(p)));
if (r > mid) res = max(res, queryMax(l, r, rs(p)));
return res;
}
int querySum(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 += querySum(l, r, ls(p));
if (r > mid) res += querySum(l, r, rs(p));
return res;
}
signed main(int argc, char *argv[]) {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
build(1, n, 1);
while (m--) {
int opt, l, r, x;
cin >> opt;
switch (opt) {
case 0:
cin >> l >> r >> x;
update(l, r, x, 1);
break;
case 1:
cin >> l >> r;
cout << queryMax(l, r, 1) << '\n';
break;
case 2:
cin >> l >> r;
cout << querySum(l, r, 1) << '\n';
break;
}
}
}
system("pause");
return 0;
}
字典树
class Trie {
private:
static const int MAXN = 1e5 + 5;
static const int BASE = 30;
int idx = 1, trie[MAXN * BASE][2];
public:
inline void insert(int x) {
int u = 1;
for (int i = BASE; i >= 0; --i) {
int v = (x >> i) & 1;
if (!trie[u][v]) {
trie[u][v] = ++idx;
}
u = trie[u][v];
}
}
inline int find(int x) {
int u = 1, res = 0;
for (int i = BASE; i >= 0; --i) {
int v = (x >> i) & 1;
if (trie[u][v ^ 1]) {
u = trie[u][v ^ 1];
res |= 1 << i;
v ^= 1;
}
else {
u = trie[u][v];
}
}
return res;
}
inline void clear() {
for (int i = 1; i <= idx; ++i) {
trie[i][0] = 0;
trie[i][1] = 0;
}
idx = 1;
}
};
线性基
class LinearBasis {
private:
static const int BASE = 63;
static const int MAXL = 100 + 5;
int d[MAXL], cnt, p[MAXL];
public:
inline LinearBasis() {
cnt = 0;
memset(p, 0, sizeof(p));
memset(d, 0, sizeof(d));
}
inline bool insert(int x) {
for (int i = BASE; i >= 0; --i) {
if (x & (1LL << i)) {
if (!d[i]) {
d[i] = x;
break;
}
x ^= d[i];
}
}
return x;
}
inline void rebuild() {
for (int i = BASE; i >= 0; --i) {
for (int j = i - 1; j >= 0; --j) {
if (d[i] & (1LL << j)) {
d[i] ^= d[j];
}
}
}
for (int i = 0; i <= BASE; ++i) {
if (d[i]) {
p[cnt++] = d[i];
}
}
}
inline int kth(int k) {
int res = 0;
if (k >= (1LL << cnt)) return -1;
for (int i = BASE; i >= 0; --i) {
if (k & (1LL << i)) {
res ^= p[i];
}
}
return res;
}
inline int queryMin() {
for (int i = 0; i <= BASE; ++i) {
if (d[i]) {
return d[i];
}
}
return 0;
}
inline int queryMax() {
int res = 0;
for (int i = BASE; i >= 0; --i) {
res = max(res, res ^ d[i]);
}
return res;
}
inline int queryMin(int x) {
for (int i = BASE; i >= 0; --i) {
x = min(x, x ^ d[i]);
}
return x;
}
inline int queryMax(int x) {
for (int i = BASE; i >= 0; --i) {
x = max(x, x ^ d[i]);
}
return x;
}
};