几个板子

 


FHQ Treap#

普通平衡树

struct treap {
	int l, r, siz, dat, val;
} tr[N];
int idx, rt;
int get_new(int val) {
	tr[++ idx].val = val;
	tr[idx].dat = rand();
	tr[idx].siz = 1;
	return idx;
}
void pushup(int u) {
	tr[u].siz = tr[tr[u].l].siz + tr[tr[u].r].siz + 1;
}
void split(int u, int v, int &x, int &y) {
	if(!u) x = y = 0;
	else {
		if(tr[u].val <= v) x = u, split(tr[x].r, v, tr[x].r, y);
		else y = u, split(tr[y].l, v, x, tr[y].l);
		pushup(u);
	}
}
int merge(int x, int y) {
	if(!x || !y) return x + y;
	if(tr[x].dat < tr[y].dat) {
		tr[x].r = merge(tr[x].r, y);
		pushup(x);
		return x;
	}
	else {
		tr[y].l = merge(x, tr[y].l);
		pushup(y);
		return y;
	}
}
void insert(int val) {
	int x, y, z;
	split(rt, val, x, y);
	z = get_new(val);
	rt = merge(merge(x, z), y);
}
void remove(int val) {
	int x, y, z;
	split(rt, val, x, z);
	split(x, val - 1, x, y);
	y = merge(tr[y].l, tr[y].r);
	rt = merge(merge(x, y), z);
}
int get_rk_by_val(int val) {
	int x, y, res;
	split(rt, val - 1, x, y);
	res = tr[x].siz + 1;
	rt = merge(x, y);
	return res;
}
int get_val_by_rk(int u, int rk) {
	if(rk <= tr[tr[u].l].siz) return get_val_by_rk(tr[u].l, rk);
	else if(rk == tr[tr[u].l].siz + 1) return tr[u].val;
	return get_val_by_rk(tr[u].r, rk - tr[tr[u].l].siz - 1);
}
int get_pre(int val) {
	int x, y, res;
	split(rt, val - 1, x, y);
	res = get_val_by_rk(x, tr[x].siz);
	rt = merge(x, y);
	return res;
}
int get_nxt(int val) {
	int x, y, res;
	split(rt, val, x, y);
	res = get_val_by_rk(y, 1);
	rt = merge(x, y);
	return res;
}

文艺平衡树#

struct Treap {
	int l, r, val, dat, siz, tag;
} tr[N];
int idx, rt;
void pushup(int u) {
	tr[u].siz = tr[tr[u].l].siz + tr[tr[u].r].siz + 1;
}
void pushdown(int u) {
	if(!tr[u].tag) return;
	swap(tr[u].l, tr[u].r);
	tr[tr[u].l].tag ^= 1;
	tr[tr[u].r].tag ^= 1;
	tr[u].tag = 0;
}
int get_new(int val) {
	tr[++ idx].val = val;
	tr[idx].dat = rand();
	tr[idx].siz = 1;
	return idx;
}
void split(int u, int sz, int &x, int &y) {
	if(!u) {
		x = y = 0;
		return;
	}
	pushdown(u);
	if(tr[tr[u].l].siz < sz) {
		x = u;
		split(tr[u].r, sz - tr[tr[u].l].siz - 1, tr[x].r, y);
	}
	else {
		y = u;
		split(tr[u].l, sz, x, tr[y].l);
	}
	pushup(u);
}
int merge(int x, int y) {
	if(!x || !y) return x + y;
	if(tr[x].dat < tr[y].dat) {
		pushdown(y);
		tr[y].l = merge(x, tr[y].l);
		pushup(y);
		return y;
	}
	else {
		pushdown(x);
		tr[x].r = merge(tr[x].r, y);
		pushup(x);
		return x;
	}
}
void reverse(int l, int r) {
	int x, y, z;
	split(rt, r, y, z);
	split(y, l - 1, x, y);
	tr[y].tag ^= 1;
	rt = merge(x, merge(y, z));
}
void output(int u) {
	if(!u) return;
	pushdown(u);
	output(tr[u].l);
	cout << tr[u].val << ' ';
	output(tr[u].r);
}

Treap#

struct treap {
	int l, r;
	int val, dat;
	int cnt, siz;
} tr[N];
int idx, rt;
int get_new(int val) {
	tr[++ idx].val = val;
	tr[idx].dat = rand();
	tr[idx].siz = tr[idx].cnt = 1;
	return idx;
}
void pushup(int x) {
	tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + tr[x].cnt;
}
void zig(int &x) {
	int y = tr[x].l;
	tr[x].l = tr[y].r, tr[y].r = x, x = y;
	pushup(tr[x].r), pushup(x);
}
void zag(int &x) {
	int y = tr[x].r;
	tr[x].r = tr[y].l, tr[y].l = x, x = y;
	pushup(tr[x].l), pushup(x);
}
void insert(int &x, int val) {
	if(x == 0) {
		x = get_new(val);
		return;
	}
	if(val == tr[x].val) {
		tr[x].cnt ++, pushup(x);
		return;
	}
	if(val < tr[x].val) {
		insert(tr[x].l, val);
		if(tr[tr[x].l].dat > tr[x].dat) zig(x);
	}
	else if(val > tr[x].val) {
		insert(tr[x].r, val);
		if(tr[tr[x].r].dat > tr[x].dat) zag(x);
	}
	pushup(x);
}
void remove(int &x, int val) {
	if(x == 0) return;
	if(tr[x].val == val) {
		if(tr[x].cnt > 1) {
			tr[x].cnt --;
			pushup(x);
			return;
		}
		if(tr[x].l || tr[x].r) {
			if(tr[x].r == 0 || tr[tr[x].l].dat > tr[tr[x].r].dat)
				zig(x), remove(tr[x].r, val);
			else
				zag(x), remove(tr[x].l, val);
			pushup(x);
		}
		else x = 0;
		return;
	}	
	if(val < tr[x].val) remove(tr[x].l, val);
	else remove(tr[x].r, val);
	pushup(x);
}
int get_rk_by_val(int x, int val) {
	if(x == 0) return 0;
	if(val == tr[x].val) return tr[tr[x].l].siz + 1;
	if(val < tr[x].val) return get_rk_by_val(tr[x].l, val);
	return tr[tr[x].l].siz + tr[x].cnt + get_rk_by_val(tr[x].r, val);
}
int get_val_by_rk(int x, int rk) {
	if(x == 0) return INF;
	if(tr[tr[x].l].siz >= rk) return get_val_by_rk(tr[x].l, rk);
	if(tr[tr[x].l].siz + tr[x].cnt >= rk) return tr[x].val;
	return get_val_by_rk(tr[x].r, rk - tr[tr[x].l].siz - tr[x].cnt);
}
int get_pre(int x, int val) {
	if(x == 0) return -INF;
	if(val <= tr[x].val) return get_pre(tr[x].l, val);
	return max(tr[x].val, get_pre(tr[x].r, val)); 
}
int get_nxt(int x, int val) {
	if(x == 0) return INF;
	if(val >= tr[x].val) return get_nxt(tr[x].r, val);
	return min(tr[x].val, get_nxt(tr[x].l, val));
}

树状数组#

struct BIT {
	int n;
	vector<int> c;
	void init(int N) {
		n = N;
		c.resize(n + 1);
	}
	#define lbt(x) x & -x
	void modify(int x, int v) {
		for(; x <= n; x += lbt(x)) c[x] += v;
	}
	int query(int x) {
		int res = 0;
		for(; x; x -= lbt(x)) res += c[x];
		return res;
	}
} bit;

线段树#

区间修区间查#

struct Tag {

    bool empty () {
	
    }
    void clear() {
    	
    }
};

struct Info {
	
};

Info operator + (Info lhs, Info rhs) {
	
}

Info operator + (Info lhs, Tag rhs) {
	
}

Tag operator +(Tag lhs, Tag rhs) {
	
}

struct Segment_Tree {
    struct Node {
        int l, r;
        Info val;
        Tag tag;
        void apply(Tag v) {
            val = val + v;
            tag = tag + v;
            return;
        }

        #define l(x) tr[x].l
        #define r(x) tr[x].r
        #define val(x) tr[x].val
        #define tag(x) tr[x].tag
    } tr[N << 2];

    void pushdown(int x) {
        if (tag(x).empty()) {
            return;
        }
        tr[x * 2].apply(tag(x)), tr[x * 2 + 1].apply(tag(x));
        tag(x).clear();
    }

    void build(int l, int r, int x) {
        tr[x] = {l, r};
        tag(x).clear();
        if (l == r) {
            
            return;
        }
        int mid = (l + r) / 2;
        build(l, mid, x * 2), build(mid + 1, r, x * 2 + 1);
        val(x) = val(x * 2) + val(x * 2 + 1);
    }

    void update(int l, int r, int x, Tag v) {
        if (l <= l(x) && r(x) <= r) {
            tr[x].apply(v);
            return;
        }
        pushdown(x);
        int mid = (l(x) + r(x)) / 2;
        if (l <= mid) {
            update(l, r, x * 2, v);
        } 
        if (r > mid) {
            update(l, r, x * 2 + 1, v);
        }
        val(x) = val(x * 2) + val(x * 2 + 1);
    }

    Info query(int l, int r, int x) {
        if (l <= l(x) && r(x) <= r) return val(x);
        pushdown(x);
        int mid = (l(x) + r(x)) / 2;
        if (r <= mid) {
            return query(l, r, x * 2);
        } else if (l > mid) {
            return query(l, r, x * 2 + 1);
        } else {
            return query(l, r, x * 2) + query(l, r, x * 2 + 1);
        }
    }

} SegT;

单调修区间查#

struct Tag {
	
    bool empty () {
    	
    }
    void clear() {
    	
    }
};

struct Info {
	
};

Info operator + (Info lhs, Info rhs) {
	
}

Info operator + (Info lhs, Tag rhs) {
	
}

Tag operator +(Tag lhs, Tag rhs) {
	
}

struct Segment_Tree {
    struct Node {
        int l, r;
        Info val;

        #define l(x) tr[x].l
        #define r(x) tr[x].r
        #define val(x) tr[x].val
        #define tag(x) tr[x].tag
    } tr[N << 2];

    void build(int l, int r, int x) {
        tr[x] = {l, r};
        tag(x).clear();
        if (l == r) {
		
            return;
        }
        int mid = (l + r) / 2;
        build(l, mid, x * 2), build(mid + 1, r, x * 2 + 1);
        val(x) = val(x * 2) + val(x * 2 + 1);
    }

    void update(int p, int x, Info v) {
        if (l(x) == r(x)) {
            
            return;
        }
        pushdown(x);
        int mid = (l(x) + r(x)) / 2;
        if (l <= mid) {
            update(l, r, x * 2, v);
        } 
        if (r > mid) {
            update(l, r, x * 2 + 1, v);
        }
        val(x) = val(x * 2) + val(x * 2 + 1);
    }

    Info query(int l, int r, int x) {
        if (l <= l(x) && r(x) <= r) return val(x);
        int mid = (l(x) + r(x)) / 2;
        if (r <= mid) {
            return query(l, r, x * 2);
        } else if (l > mid) {
            return query(l, r, x * 2 + 1);
        } else {
            return query(l, r, x * 2) + query(l, r, x * 2 + 1);
        }
    }

} SegT;

树链剖分#

void dfs1(int u, int fath) {
	fa[u] = fath;
	dep[u] = dep[fath] + 1;
	siz[u] = 1;
	for(auto v : e[u]) {
		if(v == fath) continue;
		dfs1(v, u);
		siz[u] += siz[v];
		if(siz[v] > siz[son[u]])
			son[u] = v;
	}
}
void dfs2(int u, int fst) {
	id[u] = ++ idx;
	a[idx] = w[u];
	top[u] = fst;
	if(!son[u]) return;
	dfs2(son[u], fst);
	for(auto v:e[u]) {
		if(v == fa[u] || v == son[u]) continue;
		dfs2(v, v);
	}
}

快速幂#

int power(int a, int b) {
	int res = 1;
	for(; b; a = (LL)a * a % mod, b >>= 1) if(b & 1) res = res * a % mod; 
	return res;
}

ST表#

for(int j = 1; (1 << j) <= n; j ++)
		for(int i = 1; i + (1 << j) - 1 <= n; i ++)
			f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);

dijkstra#

void duijkstra() {
	for(int i = 1; i <= n; i ++) dist[i] = INF, st[i] = false;
	priority_queue<PII, vector<PII>, greater<PII> > q;
	dist[s] = 0;
	q.push({0, s});
	while(q.size()) {
		int u = q.top().se;
		q.pop();
		if(st[u]) continue;
		st[u] = true;
		for(int i = h[u]; i; i = nxt[i]) {
			int v = to[i], w = val[i];
			if(dist[v] > dist[u] + w) {
				dist[v] = dist[u] + w;
				q.push({dist[v], v});
			}
		}
	}
}

加边#

int h[N], nxt[M << 1], to[M << 1], val[M << 1], cnt;
void add(int u, int v, int w) {
	to[++ cnt] = v, val[cnt] = w, nxt[cnt] = h[u], h[u] = cnt;
}
int h[N], nxt[M << 1], to[M << 1], cnt;
void add(int u, int v) {
	to[++ cnt] = v, nxt[cnt] = h[u], h[u] = cnt;
}

LCA#

void dfs(int u, int fath) {
    dep[u] = dep[fath] + 1, fa[u][0] = fath;
    for(int i = 1;i <= __lg(dep[u]);i ++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
    for(int i = h[u]; i; i = nxt[i])
    {
        int v = to[i];
        if(v == fath) continue;
        dfs(v, u);
    }
}
int lca(int u, int v)
{
    if(dep[u] < dep[v]) swap(u, v);
    while(dep[u] > dep[v]) u = fa[u][__lg(dep[u] - dep[v])];
    if(u == v) return u;
    for(int k = __lg(dep[u]); ~k; k --)
        if(fa[u][k] != fa[v][k]) u = fa[u][k], v = fa[v][k];
    return fa[u][0];
}

DSU#

int fa[N];
void dsu_clear() {
    for(int i = 1;i <= n;i ++) fa[i] = i;
}
int find(int x) {
	if(fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
void merge(int x, int y) {
	fa[find(x)] = find(y);
}

最小生成树#

	sort(e + 1, e + 1 + m);
	ll res = 0;
	for(int i = 1; i <= m; i ++) {
		int u = find(e[i].u), v = find(e[i].v);
		if(u == v) continue;
		res += e[i].w;
		merge(u, v);
	}

Floyd#

for(int i = 1; i <= n; i ++) f[i][i] = 0;
	for(int k = 1; k <= n; k ++)
		for(int i = 1; i <= n; i ++)
			for(int j = 1; j <= n; j ++) 
				f[i][j] = min(f[i][j], f[i][k] + f[k][j]);

矩阵快速幂#

struct matrix {
	LL c[105][105];
} A;
LL n, k;
matrix operator *(const matrix &a, const matrix &b) {
	matrix c;
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= n; j ++) c.c[i][j] = 0;
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= n; j ++)
			for(int k = 1; k <= n; k ++)
				c.c[i][j] = (c.c[i][j] + a.c[i][k] * b.c[k][j]) % mod;
	return c;
}
matrix qpow(matrix a, ll b)
{
	matrix res;
	for(int i = 1; i <= n; i ++) res.c[i][i] = 1;
	for(; b; a = a * a, b >>= 1)if(b & 1) res = res * a;
	return res;
}

最大流#

template <class Type>
struct Flow {
	int h[N], nxt[M << 1], to[M << 1], cnt;
	int S, T;
	Type val[M << 1];
	int cur[N], d[N];
	void init(int _S, int _T) {
		S = _S, T = _T, cnt = 1;
	}
	void add(int u, int v, Type w) {
		to[++ cnt] = v, val[cnt] = w, nxt[cnt] = h[u], h[u] = cnt;
		to[++ cnt] = u, val[cnt] = 0, nxt[cnt] = h[v], h[v] = cnt;
	}
	bool bfs() {
		memset(d, -1, sizeof d);
		d[S] = 0, cur[S] = h[S];
		queue<int> q;
		q.push(S);
		while(q.size()) {
			int u = q.front();
			q.pop();
			for(int i = h[u]; i; i = nxt[i]) {
				int v = to[i];
				if(d[v] == -1 && val[i]) {
					d[v] = d[u] + 1;
					cur[v] = h[v];
					if(v == T) return true;
					q.push(v);
				}
			}
		}
		return false;
	}
	Type dfs(int u, Type lim) {
		if(u == T) return lim;
		Type flow = 0;
		for(int i = cur[u]; i && flow < lim; i = nxt[i]) {
			cur[u] = i;
			int v = to[i];
			if(d[v] == d[u] + 1 && val[i]) {
				int t = dfs(v, min(val[i], lim - flow));
				if(!t) d[v] = -1;
				flow += t, val[i] -= t, val[i ^ 1] += t;
			}
		}
		return flow;
	}
	Type dinic() {
		Type flow, res = 0;
		while(bfs()) while(flow = dfs(S, INF)) res += flow;
		return res;
	}
};

Modint#

template <typename T>  T power(T a, ll b) {
    T c{1}; for (; b; b /= 2, a *= a) if (b & 1) c *= a;
    return c;
}
template <int P> struct MInt {
    int x;
    MInt() : x{} {}
    MInt(ll x_) : x{norm(x_ % getMod())} {}
    static int Mod;
    static int getMod() { return P > 0 ? P : Mod; }
    static void setMod(int Mod_) { Mod = Mod_; }
    int up(int x) const {
        if (x < 0) x += getMod();
        return x;
    }
    int down(int x) const {
        if (x >= getMod()) x -= getMod();
        return x;
    }
    int norm(int x) const {
        return up(down(x));
    }
    int val() const { return x; }
    explicit  operator int() const { return x; }
    MInt operator-() const {
        MInt res; res.x = norm(getMod() - x); return res;
    }
    MInt inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    MInt &operator+=(MInt rhs) & { return x = down(x + rhs.x), *this; }
    MInt &operator-=(MInt rhs) & { return x = up(x - rhs.x), *this; }
    MInt &operator*=(MInt rhs) & { return x = 1ll * x * rhs.x % getMod(), *this; }
    MInt &operator/=(MInt rhs) & { return *this *= rhs.inv(); }
    friend MInt operator+(MInt lhs, MInt rhs) { return lhs += rhs; }
    friend MInt operator-(MInt lhs, MInt rhs) { return lhs -= rhs; }
    friend MInt operator*(MInt lhs, MInt rhs) { return lhs *= rhs; }
    friend MInt operator/(MInt lhs, MInt rhs) { return lhs /= rhs; }
    friend bool operator==(MInt lhs, MInt rhs) { return lhs.val() == rhs.val(); }
    friend  bool operator!=(MInt lhs, MInt rhs) { return lhs.val() != rhs.val(); }
    friend  std::istream &operator>>(std::istream &is, MInt &a) {
        ll x = 0; is >> x, a = MInt(x); return is;
    }
    friend  std::ostream &operator<<(std::ostream &os, const MInt &a) {
        return os << a.val();
    }
};
const int P = 1e9 + 7;
using Z = MInt<P>; 

Comb#

Z fac[N], infac[N];
void init(int n) {
	fac[0] = infac[0] = 1;
	for (int i = 1; i <= n; i ++) {
		fac[i] = fac[i - 1] * i;
	}
	infac[n] = (Z)1 / fac[n];
	for (int i = n - 1; i >= 1; i --) {
		infac[i] = infac[i + 1] * (i + 1);
	}
}

Z comb(int a, int b) {
	if (a < 0 || b < 0 || a < b) return 0;
	return fac[a] * infac[a - b] * infac[b];
} 
posted @   Svemit  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
主题色彩