树状数组

单点修改&区间求和

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;
    }
};