板子

基本

缺省源

#include <bits/stdc++.h>
#define mp std::make_pair
#define pb push_back
#define fi first
#define se second
#define gc getchar
#define pc putchar
#define ep emplace
#define eb emplace_back
#define ctz __builtin_ctz
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef std::pair <int, int> pii;
typedef std::pair <int, ll> pil;
typedef std::pair <ll, int> pli;
typedef std::pair <ll, ll> pll;
int read() {
	char c = gc(); int ans = 0; bool flag = true;
	while (!isdigit(c)) flag &= (c != '-'), c = gc();
	while (isdigit(c)) ans = ans * 10 + c - '0', c = gc();
	return flag ? ans : -ans;
}
void Write(int x) {
	if (x < 0) pc('-'), x = -x;
	if (x < 10) pc(x + '0');
	else Write(x / 10), pc(x % 10 + '0');
}
int min(int x, int y) {return x < y ? x : y;}
int max(int x, int y) {return x > y ? x : y;}
void _min(int &x, int y) {if (x > y) x = y;}
void _max(int &x, int y) {if (x < y) x = y;}

超快读入/输出

namespace io {
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1;
	inline char getc() {return (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++);}
	inline void flush() {fwrite(obuf, 1, oS - obuf, stdout); oS = obuf;}
	inline void putc(char x) {*oS++ = x; if (oS == oT) flush();}
	template <class T>
	inline void read(T &x) {
		char ch = getc(); bool flag = false; x = 0;
		while (!isdigit(ch)) flag |= (ch == '-'), ch = getc();
		while (isdigit(ch)) x = x * 10 + ch - '0', ch = getc();
		if (flag) x = -x;
	}
	template <class T, class ...Args>
	inline void read(T &x, Args&... args) {read(x); read(args...);}
	template <class T>
	inline void write(T x) {
		static char stk[128]; int top = 0;
		if(x == 0) {putc('0'); return;}
		if(x < 0) putc('-'), x = -x;
		while (x) stk[top++] = x % 10, x /= 10;
		while (top) putc(stk[--top] + '0');
	}
	template <class T, class ...Args>
	inline void write(T x, Args... args) {write(x); putc(' '); write(args...);}
	inline void space() {putc(' ');}
	inline void endl() {putc('
');}
	struct _flush {~_flush() {flush();}} __flush;
}
using io::read; using io::write; using io::space; using io::endl; using io::getc; using io::putc;

模大质数常用函数

int plus(int x, int y) {return (x += y) >= mod ? x - mod : x;}
int minus(int x, int y) {return (x -= y) < 0 ? x + mod : x;}
void _plus(int &x, int y) {if ((x += y) >= mod) x -= mod;}
void _minus(int &x, int y) {if ((x -= y) < 0) x += mod;}
ll sqr(int x) {return (ll)x * x % mod;}
ll power(ll x, int y, ll ans = 1) {
	for (; y; y >>= 1, x = x * x % mod)
		if (y & 1) ans = ans * x % mod;
	return ans;
}
ll _inv(int x) {return x == 1 ? 1 : (mod - mod / x) * _inv(mod % x) % mod;}
void init_fac(int n) {
	for (int i = fac[0] = 1; i <= n; i++) fac[i] = fac[i - 1] * i % mod;
	fac_inv[n] = _inv(fac[n]);
	for (int i = n; i; i--) fac_inv[i - 1] = fac_inv[i] * i % mod;
}
ll binom(int x, int y) {return x < y || y < 0 ? 0 : fac[x] * fac_inv[y] % mod * fac_inv[x - y] % mod;}

网络流

最大流

namespace maxflow {
	const int max_N = ?, max_E = ?, INF = 2e9;
	int nxt[2 * max_E], head[max_N], to[2 * max_E], cap[2 * max_E], tot;
	int dist[max_N], _head[max_N], n, S, T;
	void init(int _n, int _S, int _T) {
		n = _n, S = _S, T = _T, tot = 1;
		std::fill(head + 1, head + n + 1, 0);
	}
	void add_edge(int u, int v, int w) {
		nxt[++tot] = head[u], head[u] = tot, to[tot] = v, cap[tot] = w;
		nxt[++tot] = head[v], head[v] = tot, to[tot] = u, cap[tot] = 0;
	}
	bool BFS() {
		std::fill(dist + 1, dist + n + 1, INF);
		std::queue <int> Q; Q.push(S); dist[S] = 0;
		while (!Q.empty()) {
			int cur = Q.front(); Q.pop();
			for (int i = head[cur]; i; i = nxt[i])
				if (cap[i] > 0 && dist[to[i]] == INF)
					dist[to[i]] = dist[cur] + 1, Q.push(to[i]);
		}
		return dist[T] < INF;
	}
	int dfs(int x, int low) {
		if (x == T) return low; int used = 0, tmp;
		for (int &i = _head[x]; i; i = nxt[i])
			if (cap[i] > 0 && dist[to[i]] == dist[x] + 1) {
				tmp = dfs(to[i], min(low - used, cap[i]));
				if (tmp > 0) used += tmp, cap[i] -= tmp, cap[i ^ 1] += tmp;
				if (used == low) break;
			}
		return used;
	}
	int solve() {
		int ans = 0;
		while (BFS()) std::copy(head + 1, head + n + 1, _head + 1), ans += dfs(S, INF);
		return ans;
	}
}

最小费用最大流

namespace costflow {
	const int max_N = ?, max_M = ?, INF = 2e9;
	int nxt[2 * max_M], head[max_N], to[2 * max_M], cap[2 * max_M], cost[2 * max_M], dist[max_N], _head[max_N];
	int n, S, T, tot, maxflow, mincost;
	bool inq[max_N], vis[max_N];
	void init(int _n, int _S, int _T) {
		n = _n, S = _S, T = _T, tot = 1;
		std::fill(head + 1, head + n + 1, 0);
	}
	void add_edge(int u, int v, int w, int _cost) {
		nxt[++tot] = head[u], head[u] = tot, to[tot] = v, cap[tot] = w, cost[tot] = _cost;
		nxt[++tot] = head[v], head[v] = tot, to[tot] = u, cap[tot] = 0, cost[tot] = -_cost;
	}
	bool SPFA() {
		std::fill(dist + 1, dist + n + 1, INF);
		std::queue <int> Q; Q.push(T); dist[T] = 0, inq[T] = true;
		while (!Q.empty()) {
			int cur = Q.front(); Q.pop(); inq[cur] = false;
			for (int i = head[cur]; i; i = nxt[i])
				if (cap[i ^ 1] > 0 && dist[to[i]] > dist[cur] - cost[i]) {
					dist[to[i]] = dist[cur] - cost[i];
					if (!inq[to[i]]) Q.push(to[i]), inq[to[i]] = true;
				}
		}
		return dist[S] < INF;
	}
	int dfs(int x, int low) {
		if (x == T) return low; vis[x] = true; int used = 0, tmp;
		for (int &i = _head[x]; i; i = nxt[i])
			if (cap[i] > 0 && dist[to[i]] == dist[x] - cost[i] && !vis[to[i]]) {
				tmp = dfs(to[i], min(low - used, cap[i]));
				if (tmp > 0) cap[i] -= tmp, cap[i ^ 1] += tmp, used += tmp, mincost += tmp * cost[i];
				if (used == low) break;
			}
		return used;
	}
	void solve() {
		maxflow = mincost = 0;
		while (SPFA())
			std::copy(head + 1, head + n + 1, _head + 1),
			std::fill(vis + 1, vis + n + 1, false), maxflow += dfs(S, INF);
	}
}

有源汇有上下界最大流

namespace bounded_maxflow {
	int n, S, T, deg[maxflow::max_N];
	void init(int _n, int _S, int _T) {
		n = _n, S = _S, T = _T;
		maxflow::init(n + 2, n + 1, n + 2);
	}
	void add_edge(int u, int v, int l, int r) {
		deg[u] -= l, deg[v] += l, maxflow::add_edge(u, v, r - l);
	}
	int solve() {
		int sum = 0;
		for (int i = 1; i <= n; i++)
			if (deg[i] > 0) maxflow::add_edge(n + 1, i, deg[i]), sum += deg[i];
			else if (deg[i] < 0) maxflow::add_edge(i, n + 2, -deg[i]);
		maxflow::add_edge(T, S, maxflow::INF);
		if (maxflow::solve() != sum) return -1;
		for (int i = 1; i <= n; i++)
			for (int j = maxflow::head[i]; j; j = maxflow::nxt[j])
				if (maxflow::to[j] > n) maxflow::cap[j] = maxflow::cap[j ^ 1] = 0;
		return maxflow::S = S, maxflow::T = T, maxflow::solve();
	}
}

字符串

exKMP

namespace exKMP {
	const int max_N = ?;
	char A[max_N];
	int nxt[max_N], extend[max_N];
	void get_nxt(char *s, int n) {
		std::memcpy(A + 1, s + 1, n); A[n + 1] = 0; nxt[1] = n;
		nxt[2] = std::mismatch(A + 2, A + n + 1, A + 1).fi - (A + 2);
		for (int i = 3, tmp = 2; i <= n; i++) {
			nxt[i] = max(0, min(nxt[i - tmp + 1], nxt[tmp] + tmp - i));
			nxt[i] = std::mismatch(A + i + nxt[i], A + n + 1, A + nxt[i] + 1).fi - (A + i);
			if (i + nxt[i] > tmp + nxt[tmp]) tmp = i; 
		}
	}
	void get_extend(char *B, int m) {
		extend[1] = std::mismatch(A + 1, A + n + 1, B + 1).fi - (A + 1);
		for (int i = 2, tmp = 1; i <= m; i++) {
			extend[i] = max(0, min(nxt[i - tmp + 1], tmp + extend[tmp] - i));
			extend[i] = std::mismatch(B + i + extend[i], B + m + 1, A + extend[i] + 1).fi - (B + i);
			if (i + extend[i] > tmp + extend[tmp]) tmp = i;
		}
	}
}

数据结构

并查集

namespace DSU {
	int fa[max_N];
	void init(int n) {std::iota(fa + 1, fa + n + 1, 1);}
	int anc(int x) {return fa[x] == x ? x : fa[x] = anc(fa[x]);}
	void link(int x, int y) {fa[anc(x)] = anc(y);}
	bool connected(int x, int y) {return anc(x) == anc(y);}
	int num() {
		int ans = 0;
		for (int i = 1; i <= n; i++) ans += (fa[i] == i);
		return ans;
	}
}

线性代数

拟阵交

namespace matriod_cross {
	const int max_N = ?, INF = 2e9;
	bool flag[max_N];
	std::vector <int> G[max_N];
	int n, pre[max_N], dist[max_N];
	namespace matriod_1 {
		void build() {?}
		bool ins(int x) {?}
	}
	namespace matriod_2 {
		void build() {?}
		bool ins(int x) {?}
	}
	bool find_path() {
		for (int i = 1; i <= n + 2; i++) G[i].clear();
		matriod_1::build(), matriod_2::build();
		for (int i = 1; i <= n; i++) {
			if (flag[i]) continue; bool tmp = true;
			if (matriod_1::ins(i)) G[n + 1].pb(i); else tmp = false;
			if (matriod_2::ins(i)) G[i].pb(n + 2); else tmp = false;
			if (tmp) return flag[i] = true;
		}
		for (int i = 1; i <= n; i++) {
			if (!flag[i]) continue; flag[i] = false;
			matriod_1::build(), matriod_2::build();
			for (int j = 1; j <= n; j++) {
				if (i == j || flag[j]) continue;
				if (matriod_1::ins(j)) G[i].pb(j);
				if (matriod_2::ins(j)) G[j].pb(i);
			}
			flag[i] = true;
		}
		std::fill(dist + 1, dist + n + 3, INF);
		std::queue <int> Q; Q.push(n + 1); dist[n + 1] = 0;
		while (!Q.empty()) {
			int cur = Q.front(); Q.pop();
			for (auto i : G[cur]) if (dist[i] == INF)
				dist[i] = dist[cur] + 1, pre[i] = cur, Q.push(i);
		}
		if (dist[n + 2] == INF) return false;
		for (int i = pre[n + 2]; i != n + 1; i = pre[i]) flag[i] ^= 1;
		return true;
	}
	int solve(int _n) {
		n = _n; while (find_path());
		return std::accumulate(flag + 1, flag + n + 1, 0);
	}
}
原文地址:https://www.cnblogs.com/bestlxm/p/14253558.html