大大大大板子

枚举子集

for (int x = s; x; x = (x - 1) & s) {}
View Code

高维前缀和

for (int i = 0; i < m; ++i)
    for (int j = 0; j < (1 << m); ++j)
        if (j & (1 << i)) f[j] += f[j ^ (1 << i)];

for (int i = 0; i < m; ++i)
    for (int j = 0; j < (1 << m); ++j)
        if (!(j & (1 << i))) f[j] += f[j | (1 << i)];
View Code

线性基

void insert(long long x) {
    for (int i = 62; ~i; --i)
        if (x >> i) {
            if (!p[i]) { p[i] = x; break; }
            x ^= p[i];
        }
}
void rebuild() {
    for (int i = 62; ~i; --i)
        for (int j = i - 1; ~j; --j)
            if (p[i] & (1LL << j)) p[i] ^= p[j];
}
View Code

线性求逆元

inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = 1LL * (p - p / i) * inv[p % i] % p;
View Code

欧拉筛

void sieve() {
    np[1] = 1, phi[1] = mu[1] = 1;
    for (int i = 2; i <= n; ++i) {
        if (!np[i]) p[++tot] = i, phi[i] = i - 1, mu[i] = -1;
        for (int j = 1; j <= tot && i * p[j] <= n; ++j) {
            np[i * p[j]] = 1;
            if (i % p[j] == 0) {
                phi[i * p[j]] = phi[i] * p[j], mu[i * p[j]] = 0;
                break;
            }
            phi[i * p[j]] = phi[i] * (p[j] - 1), mu[i * p[j]] = -mu[i];
        }
    }
}
View Code

文艺平衡树

#include <cstdio>
#include <algorithm>

const int N = 100002;
int a[N], val[N], rev[N], siz[N], fa[N], ch[N][2], rt, cnt, n, m;

int read() {
    int x = 0; char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return x;
}
int get(int x) {
    return ch[fa[x]][1] == x;
}
void maintain(int x) {
    siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
}
void tab(int x) {
    rev[x] ^= 1, std::swap(ch[x][0], ch[x][1]);
}
void pushdown(int x) {
    if (ch[x][0]) tab(ch[x][0]);
    if (ch[x][1]) tab(ch[x][1]);
    rev[x] = 0;
}
void build(int &cur, int pre, int l, int r) {
    if (l > r) return;
    cur = ++cnt;
    int mid = (l + r) >> 1;
    val[cur] = a[mid], fa[cur] = pre;
    build(ch[cur][0], cur, l, mid - 1);
    build(ch[cur][1], cur, mid + 1, r);
    maintain(cur);
}
void rotate(int x) {
    int y = fa[x], z = fa[y], k = get(x);
    if (rev[y]) pushdown(y);
    if (rev[x]) pushdown(x);
    if (z) ch[z][get(y)] = x;
    ch[y][k] = ch[x][k ^ 1], ch[x][k ^ 1] = y;
    fa[ch[y][k]] = y, fa[y] = x, fa[x] = z;
    maintain(y), maintain(x);
}
void splay(int x, int z) {
    for (int y; (y = fa[x]) != z; rotate(x))
        if (fa[y] != z) rotate(get(x) ^ get(y) ? x : y);
    if (!z) rt = x;
}
int find(int k) {
    int x = rt;
    for (;;) {
        if (rev[x]) pushdown(x);
        if (siz[ch[x][0]] + 1 == k) return x;
        if (siz[ch[x][0]] >= k) x = ch[x][0];
        else k -= siz[ch[x][0]] + 1, x = ch[x][1];
    }
}
void print(int x) {
    if (rev[x]) pushdown(x);
    if (ch[x][0]) print(ch[x][0]);
    if (1 <= val[x] && val[x] <= n) printf("%d ", val[x]);
    if (ch[x][1]) print(ch[x][1]);
}
int main() {
    n = read(), m = read();
    for (int i = 2; i <= n + 1; ++i) a[i] = i - 1;
    a[1] = 0, a[n + 2] = n + 1, build(rt, 0, 1, n + 2);
    while (m--) {
        int l = read(), r = read();
        l = find(l), r = find(r + 2), splay(l, 0), splay(r, l), tab(ch[r][0]);
    }
    print(rt);
    return 0;
}
View Code

主席树

#include <cstdio>
#include <algorithm>

const int N = 200002, M = 3800002;
int a[N], b[N], sum[M], ls[M], rs[M], rt[N], cnt;

int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
    while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return x * f;
}
int find(int x, int l, int r) {
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (b[mid] == x) return mid;
        if (b[mid] < x) l = mid + 1;
        else r = mid - 1;
    }
}
void insert(int &x, int y, int l, int r, int p) {
    x = ++cnt, sum[x] = sum[y] + 1;
    if (l == r) return;
    int mid = (l + r) >> 1;
    if (p <= mid) rs[x] = rs[y], insert(ls[x], ls[y], l, mid, p);
    if (mid < p) ls[x] = ls[y], insert(rs[x], rs[y], mid + 1, r, p);
}
int query(int x, int y, int l, int r, int k) {
    if (l == r) return b[l];
    int mid = (l + r) >> 1;
    if (sum[ls[x]] - sum[ls[y]] >= k) return query(ls[x], ls[y], l, mid, k);
    return query(rs[x], rs[y], mid + 1, r, k - sum[ls[x]] + sum[ls[y]]);
}
int main() {
    int n = read(), m = read();
    for (int i = 1; i <= n; ++i) a[i] = b[i] = read();
    std::sort(b + 1, b + n + 1);
    for (int i = 1; i <= n; ++i) insert(rt[i], rt[i - 1], 1, n, find(a[i], 1, n));
    while (m--) {
        int l = read(), r = read(), k = read();
        printf("%d\n", query(rt[r], rt[l - 1], 1, n, k));
    }
    return 0;
}
View Code

二维线段树

#include <cstdio>
#include <algorithm>

int ans, n, m, q;

int read() {
    int x = 0; char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return x;
}
struct Node {
    int mx[2050], tag[2050];
    void update(int cur, int l, int r, int L, int R, int x) {
        mx[cur] = std::max(mx[cur], x);
        if (L <= l && r <= R) { tag[cur] = std::max(tag[cur], x); return; }
        int mid = (l + r) >> 1;
        if (L <= mid) update(cur << 1, l, mid, L, R, x);
        if (mid < R) update(cur << 1 | 1, mid + 1, r, L, R, x);
    }
    int query(int cur, int l, int r, int L, int R) {
        if (L <= l && r <= R) return mx[cur];
        int mid = (l + r) >> 1, res = tag[cur];
        if (L <= mid) res = std::max(res, query(cur << 1, l, mid, L, R));
        if (mid < R) res = std::max(res, query(cur << 1 | 1, mid + 1, r, L, R));
        return res;
    }
} mx[2050], tag[2050];
void update(int cur, int l, int r, int L, int R, int yl, int yr, int x) {
    mx[cur].update(1, 1, m, yl, yr, x);
    if (L <= l && r <= R) { tag[cur].update(1, 1, m, yl, yr, x); return; }
    int mid = (l + r) >> 1;
    if (L <= mid) update(cur << 1, l, mid, L, R, yl, yr, x);
    if (mid < R) update(cur << 1 | 1, mid + 1, r, L, R, yl, yr, x);
}
int query(int cur, int l, int r, int L, int R, int yl ,int yr) {
    if (L <= l && r <= R) return mx[cur].query(1, 1, m, yl, yr);
    int mid = (l + r) >> 1, res = tag[cur].query(1, 1, m, yl, yr);
    if (L <= mid) res = std::max(res, query(cur << 1, l, mid, L, R, yl, yr));
    if (mid < R) res = std::max(res, query(cur << 1 | 1, mid + 1, r, L, R, yl, yr));
    return res;
}
int main() {
    n = read() + 1, m = read() + 1, q = read();
    while (q--) {
        int d = read(), s = read(), h = read(), x = read() + 1, y = read() + 1;
        int tmp = query(1, 1, n, x, x + d - 1, y, y + s - 1) + h;
        update(1, 1, n, x, x + d - 1, y, y + s - 1, tmp), ans = std::max(ans, tmp);
    }
    printf("%d\n", ans);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/fly-in-milkyway/p/10625570.html