板子大全

数据结构

01trie

const int M = 30;
const int N = 2e5 + 5;
int n, a[N]; 

struct Trie {
	int t[N * M][2], ed[N * M], dp[N * M], tot;
	inline void clear(void) {
		for (int i = 0; i <= tot; i++) t[i][0] = t[i][1] = ed[i] = dp[i] = 0;
		tot = 0;
	}
	
	Trie(void) { clear(); }
	inline void insert(int val) {
		int pos = 0;
		for (int i = M; i >= 0; i--) {
			int b = val >> i & 1;
			if (!t[pos][b]) t[pos][b] = ++tot;
			pos = t[pos][b];
		}
		ed[pos]++;
	}
	
	inline void remove(int val) {
		int pos = 0;
		for (int i = M; i >= 0; i--) {
			int b = val >> i & 1;
			if (!t[pos][b]) break;
			pos = t[pos][b];
		}
		if (ed[pos]) ed[pos]--;
	}
	
	inline int query_min(int val) {
		int pos = 0, ret = 0;
		for (int i = M; i >= 0; i--) {
			int b = val >> i & 1;
			if (t[pos][b]) pos = t[pos][b];
			else if (t[pos][1 - b]) ret = ret | (1 << i), pos = t[pos][1 - b];
			else break;
		} return ret;
	}
	
	inline int query_max(int val) {
		int pos = 0, ret = 0;
		for (int i = M; i >= 0; i--) {
			int b = val >> i & 1; b = 1 - b;
			if (t[pos][b]) pos = t[pos][b];
			else if (t[pos][1 - b]) ret = ret | (1 << i), pos = t[pos][1 - b];
			else break;
		} return ret;
	}
	
	inline void dfs(int pos) {
		int l = t[pos][0], r = t[pos][1];
		if (l) dfs(l), chkmax(dp[pos], dp[l]);
		if (r) dfs(r), chkmax(dp[pos], dp[r]);
		if (l && r) dp[pos]++;
		if (ed[pos]) dp[pos] = 1;
	}
} T;

ddp

const int N = 1e5 + 5;
int n, m, a[N];
vector <int> G[N];

const int mod = 1e9 + 7;
inline void inc(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }
inline int qpow(int a, int b = mod - 2) {
	int ret = 1;
	for (; b; b >>= 1, a = 1ll * a * a % mod)
		if (b & 1) ret = 1ll * ret * a % mod;
	return ret;
}

const int M = 2;
struct Matrix {
	int g[M][M];
	Matrix(void) { Ms(g, -0x3F); } inline void clear(void) { *this = Matrix(); }
	inline void construct(void) { Ms(g, 0); for (int i = 1; i <= n; i++) g[i][i] = 1; }
	inline int* operator [] (const int idx) { return g[idx]; }
	inline void Swap(int x, int y) { for (int i = 1; i <= n; i++) swap(g[x][i], g[y][i]); }
	inline void Mul(int x, int k) { for (int i = 1; i <= n; i++) g[x][i] = 1ll * g[x][i] * k % mod; }
	inline void Modify(int x, int y, int k) { for (int i = 1; i <= n; i++) inc(g[x][i], 1ll * g[y][i] * k % mod); }
	inline Matrix operator * (const Matrix&rhs) {
		Matrix ret;
		for (int i = 0; i < M; i++)
		for (int j = 0; j < M; j++)
		for (int k = 0; k < M; k++) chkmax(ret.g[i][j], g[i][k] + rhs.g[k][j]);
		return ret;
	}
} val[N];

int dep[N], fat[N], dfn[N], seg[N], top[N], sze[N], son[N], lst[N], timer;
inline void DfsFir(int u) {
	sze[u] = 1;
	for (auto v : G[u]) {
		if (v == fat[u]) continue;
		fat[v] = u; dep[v] = dep[u] + 1;
		DfsFir(v); sze[u] += sze[v];
		if (sze[son[u]] < sze[v]) son[u] = v;
	}
}

int f[N][2];
inline void DfsSec(int u, int t) {
	top[u] = t; dfn[u] = ++timer;
	seg[timer] = u; chkmax(lst[t], timer);
	f[u][0] = 0, f[u][1] = a[u];
	val[u].g[0][0] = val[u].g[0][1] = 0;
	val[u].g[1][0] = a[u];
	if (son[u]) {
		DfsSec(son[u], t);
		f[u][0] += max(f[son[u]][0], f[son[u]][1]);
		f[u][1] += f[son[u]][0];
	}
	for (auto v : G[u]) {
		if (v == fat[u] || v == son[u]) continue;
		DfsSec(v, v);
		f[u][0] += max(f[v][0], f[v][1]);
		f[u][1] += f[v][0];
		val[u].g[0][0] += max(f[v][0], f[v][1]);
		val[u].g[0][1] += max(f[v][0], f[v][1]);
		val[u].g[1][0] += f[v][0];
	}
}


struct SegmentTree {
	Matrix t[N << 2];
	inline void pushup(int pos) { t[pos] = t[pos << 1] * t[pos << 1 | 1]; }
	inline void build(int pos, int l, int r) {
		if (l == r) { t[pos] = val[seg[l]]; return; }
		int mid = l + r >> 1;
		build(pos << 1, l, mid);
		build(pos << 1 | 1, mid + 1, r);
		pushup(pos);
	}
	
	inline void update(int pos, int l, int r, int x) {
		if (l == r) { t[pos] = val[seg[l]]; return; }
		int mid = l + r >> 1;
		if (x <= mid) update(pos << 1, l, mid, x);
		else update(pos << 1 | 1, mid + 1, r, x);
		pushup(pos);
	}
	
	inline Matrix query(int pos, int l, int r, int L, int R) {
		if (L <= l && R >= r) return t[pos];
		int mid = l + r >> 1; Matrix ret;
		if (L <= mid) {
			ret = query(pos << 1, l, mid, L, R);
			if (R > mid) ret = ret * query(pos << 1 | 1, mid + 1, r, L, R);
		} else if (R > mid) ret = query(pos << 1 | 1, mid + 1, r, L, R);
		return ret;
	}
} T;

inline void Modify(int x, int v) {
	val[x].g[1][0] += v - a[x]; a[x] = v;
	Matrix bef, aft;
	while (x) {
		bef = T.query(1, 1, n, dfn[top[x]], lst[top[x]]);
		T.update(1, 1, n, dfn[x]);
		aft = T.query(1, 1, n, dfn[top[x]], lst[top[x]]);
		x = fat[top[x]];
		
		val[x].g[0][0] += max(aft.g[0][0], aft.g[1][0]) - max(bef.g[0][0], bef.g[1][0]);
		val[x].g[0][1] = val[x].g[0][0];
		val[x].g[1][0] += aft.g[0][0] - bef.g[0][0];
	}
}

signed main(void) {
	read(n), read(m);
	for (int i = 1; i <= n; i++) read(a[i]);
	for (int i = 1, u, v; i < n; i++) {
		read(u), read(v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	
	DfsFir(1); DfsSec(1, 1); T.build(1, 1, n); 
	
	while (m--) {
		int x, y;
		read(x), read(y);
		Modify(x, y);
		Matrix ret = T.query(1, 1, n, 1, lst[1]);
		writeln(max(ret.g[1][0], ret.g[0][0]));
	}
	//fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}


多项式全家桶

namespace Poly {
	const int mod = 998244353;
	inline int qpow(int a, int b = mod - 2) {
		int ret = 1;
		for (; b; b >>= 1, a = 1ll * a * a % mod)
			if (b & 1) ret = 1ll * ret * a % mod;
		return ret;
	}
	
	const int Maxn = 3e5 + 5;
	int invgen = qpow(3), rev[Maxn];
	inline void NTT(int limit, int *arr, int type) {
		for (int i = 0; i < limit; i++)
			if (i < rev[i]) swap(arr[i], arr[rev[i]]);
		for (int mid = 1; mid < limit; mid <<= 1) {
			int w0 = qpow(type == 1 ? 3 : invgen, (mod - 1) / (mid << 1));
			for (int i = 0; i < limit; i += mid << 1) { int w = 1;
				for (int j = 0; j < mid; j++, w = 1ll * w * w0 % mod) {
					int x = arr[i + j], y = 1ll * w * arr[i + j + mid] % mod;
					arr[i + j] = (x + y) % mod; arr[i + j + mid] = (x - y + mod) % mod;
				}
			}
		}
		if (type == -1) {
			int invlim = qpow(limit);
			for (int i = 0; i < limit; i++) arr[i] = 1ll * arr[i] * invlim % mod;
		}
	}
	
	inline void times(int n, int *a, int *b, int *c) {
		static int f[Maxn], g[Maxn];
		int lim = 1; while (lim < n << 1) lim <<= 1;
		for (int i = 0; i < lim; i++)	
			rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (lim >> 1) : 0), f[i] = a[i], g[i] = b[i];
		NTT(lim, f, 1); NTT(lim, g, 1);
		for (int i = 0; i < lim; i++) c[i] = 1ll * f[i] * g[i] % mod;
		NTT(lim, c, -1);
	}
	
	inline void Inv(int length, int *a, int *b) {
		if (length == 1) { b[0] = qpow(a[0]); return; }
		Inv(length + 1 >> 1, a, b);
		int lim = 1; while (lim < length << 1) lim <<= 1;
		static int c[Maxn];
		for (int i = 0; i < lim; i++)
			rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (lim >> 1) : 0),
			c[i] = i < length ? a[i] : 0;
		NTT(lim, b, 1); NTT(lim, c, 1);
		for (int i = 0; i < lim; i++) b[i] = 1ll * (2 - 1ll * c[i] * b[i] % mod + mod) % mod * b[i] % mod;
		NTT(lim, b, -1); for (int i = length; i < lim; i++) b[i] = 0;
	}
	
	inline void Derivation(int length, int *a, int *b) {
		for (int i = 1; i < length; i++) b[i - 1] = 1ll * i * a[i] % mod; b[length - 1] = 0;
	}
	
	inline void Integral(int length, int *a, int *b) {
		for (int i = 1; i < length; i++) b[i] = 1ll * a[i - 1] * qpow(i) % mod; b[0] = 0;
	}
	
	inline void Getln(int length, int *a, int *b) {
		static int g[Maxn], h[Maxn];
		int lim = 1; while (lim < length << 1) lim <<= 1;
		for (int i = 0; i < lim; i++)
			rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (lim >> 1) : 0), g[i] = h[i] = 0;
		Derivation(length, a, g); Inv(length, a, h);
		NTT(lim, g, 1); NTT(lim, h, 1);
		for (int i = 0; i < lim; i++) g[i] = 1ll * g[i] * h[i] % mod;
		NTT(lim, g, -1); Integral(length, g, b);
	}
	
	inline void Getexp(int length, int *a, int *b) {
		if (length == 1) return (void) (b[0] = 1);
		Getexp(length + 1 >> 1, a, b);
		static int bln[Maxn], c[Maxn]; Getln(length, b, bln);
		int lim = 1; while (lim < length << 1) lim <<= 1;
		for (int i = 0; i < lim; i++)
			rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (lim >> 1) : 0),
			c[i] = i < length ? (a[i] + (mod - bln[i])) % mod : 0;
		c[0]++; NTT(lim, c, 1); NTT(lim, b, 1);
		for (int i = 0; i < lim; i++) b[i] = 1ll * b[i] * c[i] % mod;
		NTT(lim, b, -1); for (int i = length; i < lim; i++) b[i] = 0;
	}
	
	inline void Pow(int length, int *a, int k, int *b) {
		static int f[Maxn], g[Maxn];
		int lim = 1; while (lim < length << 1) lim <<= 1;
		for (int i = 0; i < lim; i++) {
			f[i] = g[i] = 0; if (i < length) f[i] = a[i];
		}
		
		Getln(length, f, g);
		for (int i = 0; i < length; i++) g[i] = 1ll * g[i] * k % mod, f[i] = 0;
		Getexp(length, g, f);
		for (int i = 0; i < length; i++) b[i] = f[i];
	}
}

CRT

inline void exgcd(ll a, ll b, ll&x, ll&y) {
	if (!b) { x = 1, y = 0; return; }
	exgcd(b, a % b, x, y);
	ll z = x; x = y; y = z - y * (a / b);
}

const int Maxn = 15;
int n; ll a[Maxn], m[Maxn];
ll M = 1ll, mi[Maxn], ret = 0;

signed main(void) {
//	file("");
	read(n); for (int i = 1; i <= n; i++) read(m[i]), read(a[i]), M *= m[i];
	for (int i = 1; i <= n; i++) {
		mi[i] = M / m[i];
		ll inv, y; exgcd(mi[i], m[i], inv, y);
		inv = inv < 0 ? inv + m[i] : inv;
		ret = (ret + mi[i] * inv * a[i] % M) % M;
	} writeln(ret < 0 ? ret + M : ret % M);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

EXCRT

const int Maxn = 100005;
inline ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (b == 0) { x = 1; y = 0; return a; }
	ll d = exgcd(b, a % b, x, y);
	ll z = x; x = y; y = z - y * (a / b);
	return d;
}

inline ll qmul(ll a, ll k, ll p) {
	ll ret = 0;
	for (; k; k >>= 1, a = (a + a) % p)
		if (k & 1) ret = (ret + a) % p;
	return ret;
}

ll M, n, a[Maxn], m[Maxn], inv, ret = 0, y;

signed main(void) {
//	file("");
	read(n);
	for (int i = 1; i <= n; i++) read(m[i]), read(a[i]);
	ret = a[1], M = m[1];
	for (int i = 2; i <= n; i++) {
//		if (abs(a[i] - ret) % gcd(m[i], M)) { puts("-1"); return 0; }
		ll C = ((a[i] - ret) % m[i] + m[i]) % m[i];
		ll D = exgcd(M, m[i], inv, y);
		inv = qmul(inv, C / D, m[i]);
		ret += M * inv, M *= m[i] / D;
		ret = (ret + M) % M;
	} writeln(ret < 0 ? (ret + M * 2) % M : ret % M);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

线性基

const int Maxn = 55; int n;
struct LinearBasis {
	ll p[Maxn], q[Maxn], tmp[Maxn]; int cnt = 0; bool flg;
	LinearBasis(void){ Ms(p, 0), Ms(tmp, 0), flg = false; }
	inline void insert(ll x) {
		for (int i = 62; ~i; i--) {
			if (!(x & (1ll << i))) continue;
			if (!p[i]) { p[i] = x; return; }
			x ^= p[i];
		} flg = true;
	}
	
	inline ll querymax(void) {
		ll ret = 0ll;
		for (int i = 62; ~i; i--)
			chkmax(ret, ret ^ p[i]);
		return ret;
	}
	
	inline ll querymin(void) {
		if (flg) return 0ll;
		for (int i = 0; i <= 62; i++)
			if (p[i]) return p[i];
	}
	
	inline void constructkth(void) {
		memcpy(q, p, sizeof p ); cnt = 0;
		for (int i = 0; i <= 62; i++) {
			for (int j = i - 1; ~j; j--)
				if (q[i] & (1ll << j)) q[i] ^= q[j];
			if (q[i]) tmp[++cnt] = q[i];
		}
	}
	
	inline ll select(int kth) {
		if (flg) --kth; ll ret = 0ll;
		if (!kth) return 0ll;
		if (kth >= 1ll << cnt) return -1ll;
		for (int i = 0; i < cnt; i++)
			if (kth & (1ll << i)) ret ^= tmp[i + 1];
		return ret;
	}
} lbs;

矩阵求逆

const int mod = 1e9 + 7;
inline void inc(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }
inline int qpow(int a, int b = mod - 2) {
	int ret = 1;
	for (; b; b >>= 1, a = 1ll * a * a % mod)
		if (b & 1) ret = 1ll * ret * a % mod;
	return ret;
}

const int N = 405; int n;
struct Matrix {
	int g[N][N];
	Matrix(void) { Ms(g, 0); } inline void clear(void) { *this = Matrix(); }
	inline void construct(void) { clear(); for (int i = 1; i <= n; i++) g[i][i] = 1; }
	inline int* operator [] (const int idx) { return g[idx]; }
	inline void Swap(int x, int y) { for (int i = 1; i <= n; i++) swap(g[x][i], g[y][i]); }
	inline void Mul(int x, int k) { for (int i = 1; i <= n; i++) g[x][i] = 1ll * g[x][i] * k % mod; }
	inline void Modify(int x, int y, int k) { for (int i = 1; i <= n; i++) inc(g[x][i], 1ll * g[y][i] * k % mod); }
} a, b;

signed main(void) {
	read(n); b.construct();
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++) read(a[i][j]);
	for (int i = 1; i <= n; i++) {
		if (!a[i][i]) {
			for (int j = i + 1; j <= n; j++)
				if (a[j][i]) { a.Swap(i, j), b.Swap(i, j); break; }
		}
		if (!a[i][i]) { puts("No Solution"); return 0; }
		int inv = qpow(a[i][i]);
		a.Mul(i, inv); b.Mul(i, inv);
		for (int j = i + 1; j <= n; j++)
			b.Modify(j, i, mod - a[j][i]), a.Modify(j, i, mod - a[j][i]); // ´ÎÐò²»Äܵ÷£¡£¡£¡ 
	}
	for (int i = n - 1; i >= 1; i--)
	for (int j = i + 1; j <= n; j++)
		b.Modify(i, j, mod - a[i][j]), a.Modify(i, j, mod - a[i][j]);
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++) println(b[i][j], " \n"[j == n]);
	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

行列式

const int N = 605;
int n, p, a[N][N];

signed main(void) {
	read(n), read(p);
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++) read(a[i][j]), a[i][j] %= p;
	
	int f = 1, ret = 1;
	for (int i = 1, r = 1; i <= n; r = ++i) {
		for (int j = i; j <= n; j++) if (a[j][i]) { r = j; break; }
		if (!a[r][i]) { writeln(0); return 0; }
		if (i != r) swap(a[i], a[r]), f = -f;
		for (int j = i + 1; j <= n; j++) {
			if (a[j][i] > a[i][i]) swap(a[j], a[i]), f = -f;
			while (a[j][i]) {
				int tmp = a[i][i] / a[j][i];
				for (int k = i; k <= n; k++) a[i][k] = (a[i][k] + 1ll * (p - tmp) * a[j][k]) % p;
				swap(a[j], a[i]); f = -f;
			}
		} ret = 1ll * ret * a[i][i] % p;
	}
	
	ret *= f; ret = ret < 0 ? ret + p : ret; writeln(ret);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

LCT

const int Maxn = 3e5 + 5;
struct LinkCutTree {
	int val[Maxn], sum[Maxn], ch[Maxn][2], fat[Maxn]; bool rev[Maxn];
	inline bool check(int pos) { return ch[fat[pos]][1] == pos; }
	inline bool notroot(int pos) { return ch[fat[pos]][0] == pos || ch[fat[pos]][1] == pos; }
	inline void pushup(int pos) { sum[pos] = sum[ch[pos][0]] ^ sum[ch[pos][1]] ^ val[pos]; }
	inline void pushdown(int pos) { if (rev[pos]) rev[ch[pos][0]] ^= 1, rev[ch[pos][1]] ^= 1, swap(ch[pos][0], ch[pos][1]), rev[pos] = 0; }
	inline void makeall(int pos) { if (notroot(pos)) makeall(fat[pos]); pushdown(pos); }
	inline void rotate(int x) {
		int y = fat[x], d = check(x);
		fat[x] = fat[y]; if (notroot(y)) ch[fat[y]][check(y)] = x;
		if (ch[x][d ^ 1]) fat[ch[x][d ^ 1]] = y;
		ch[y][d] = ch[x][d ^ 1], ch[x][d ^ 1] = y; fat[y] = x;
		pushup(y), pushup(x);
	}
	
	inline void splay(int x) {
		makeall(x);
		while (notroot(x)) {
			if (notroot(fat[x])) {
				if (check(x) == check(fat[x])) rotate(fat[x]);
				else rotate(x);
			} rotate(x);
		}
	}
	
	inline void access(int x) { for (int y = 0; x; y = x, x = fat[x]) splay(x), ch[x][1] = y, pushup(x); }
	inline void makeroot(int x) { access(x), splay(x), rev[x] ^= 1, pushdown(x); }
	inline int findroot(int x) { access(x), splay(x), pushdown(x); while (ch[x][0]) x = ch[x][0], pushdown(x); splay(x); return x; }
	inline void split(int x, int y) { makeroot(x), access(y), splay(y); }
	inline void link(int x, int y) { makeroot(x); if (findroot(y) != x) fat[x] = y; }
	inline void cut(int x, int y) { split(x, y); if (ch[y][0] == x && !ch[y][1]) ch[y][0] = fat[x] = 0; }
	inline void modify(int x, int y) { splay(x); val[x] = y; pushup(x); }
	inline int query(int x, int y) { split(x, y); return sum[y]; }
} lct;

int n, m, x, y, opt;

signed main(void) {
	read(n), read(m);
	for (int i = 1; i <= n; i++) read(lct.val[i]);
	while (m--) {
		read(opt), read(x), read(y);
		if (opt == 0) writeln(lct.query(x, y));
		else if (opt == 1) lct.link(x, y);
		else if (opt == 2) lct.cut(x, y);
		else lct.modify(x, y);
	}
	return 0;
}

FWT

const int mod = 998244353, Maxn = 1 << 17;
int n, a[Maxn + 5], b[Maxn + 5], A[Maxn + 5], B[Maxn + 5], lim;

inline void M(int &x) {
	while (x < 0) x += mod;
	while (x >= mod) x -= mod;
}

inline void FWTor(int limit, int *arr, int type) {
	for (int mid = 1; mid < limit; mid <<= 1)
		for (int i = 0; i < limit; i += mid << 1)
			for (register int j = 0; j < mid; j++) {
				arr[i + j + mid] += arr[i + j] * type;
				M(arr[i + j + mid]);
			}
}

inline void FWTand(int limit, int *arr, int type) {
	for (int mid = 1; mid < limit; mid <<= 1)
		for (int i = 0; i < limit; i += mid << 1)
			for (register int j = 0; j < mid; j++) {
				arr[i + j] += arr[i + j + mid] * type;
				M(arr[i + j]);
			}

}

inline void div2(int &x) { x = (x & 1) ? (x + mod) >> 1 : x >> 1; }

inline void FWTxor(int limit, int *arr, int type) {
	for (int mid = 1; mid < limit; mid <<= 1)
		for (int i = 0; i < limit; i += mid << 1)
			for (register int j = 0; j < mid; j++) {
				int x = arr[i + j], y = arr[i + j + mid];
				arr[i + j] = x + y, arr[i + j + mid] = x - y;
				M(arr[i + j]), M(arr[i + j + mid]);
				if (type == -1) div2(arr[i + j]), div2(arr[i + j + mid]);
			}
}

signed main(void) {
//	file("");
	read(n); lim = 1 << n;
	for (int i = 0; i < lim; i++) read(a[i]), A[i] = a[i];
	for (int i = 0; i < lim; i++) read(b[i]), B[i] = b[i];
	FWTor(lim, A, 1), FWTor(lim, B, 1);
	for (int i = 0; i < lim; i++) A[i] = 1ll * A[i] * B[i] % mod;
	FWTor(lim, A, -1); for (int i = 0; i < lim; i++) writeln(A[i], ' '); puts("");
	
	for (int i = 0; i < lim; i++) A[i] = a[i];
	for (int i = 0; i < lim; i++) B[i] = b[i];
	FWTand(lim, A, 1), FWTand(lim, B, 1);
	for (int i = 0; i < lim; i++) A[i] = 1ll * A[i] * B[i] % mod;
	FWTand(lim, A, -1); for (int i = 0; i < lim; i++) writeln(A[i], ' '); puts("");
	
	for (int i = 0; i < lim; i++) A[i] = a[i];
	for (int i = 0; i < lim; i++) B[i] = b[i];
	FWTxor(lim, A, 1), FWTxor(lim, B, 1);
	for (int i = 0; i < lim; i++) A[i] = 1ll * A[i] * B[i] % mod;
	FWTxor(lim, A, -1); for (int i = 0; i < lim; i++) writeln(A[i], ' '); puts("");
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

最大流

const int INF = 1 << 29;

const int Maxn = 205, Maxm = 1e4 + 5;
int n, m, s, t, cnt = 1, head[Maxn], cur[Maxn], ver[Maxm], nxt[Maxm], edge[Maxm];
inline void AddEdge(int u, int v, int w) {
	ver[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt;
	ver[++cnt] = u, edge[cnt] = 0, nxt[cnt] = head[v], head[v] = cnt;
}

ll maxflow = 0; int dis[Maxn];
inline bool bfs(void) {
	Ms(dis, 0); dis[s] = 1;
	queue <int> q; q.push(s);
	while (!q.empty()) {
		int u = q.front(); q.pop();
		for (int i = head[u]; i; i = nxt[i]) {
			if (edge[i] && !dis[ver[i]]) {
				q.push(ver[i]);
				dis[ver[i]] = dis[u] + 1;
				if (ver[i] == t) return true;
			}
		}
	} return false;
}

inline int dinic(int u, int flow) {
	if (u == t) return flow;
	int rest = flow, k;
	for (int &i = cur[u]; i; i = nxt[i]) {
		if (edge[i] && dis[ver[i]] == dis[u] + 1) {
			k = dinic(ver[i], min(rest, edge[i]));
			if (!k) dis[ver[i]] = 0;
			edge[i] -= k, edge[i ^ 1] += k;
			rest -= k; if (rest == 0) break;
		}
	} return flow - rest;
}

signed main(void) {
	read(n), read(m), read(s), read(t);
	for (int i = 1, u, v, w; i <= m; i++)
		read(u), read(v), read(w), AddEdge(u, v, w);
	while (bfs()) {
		for (int i = 1; i <= n; i++) cur[i] = head[i];
		maxflow += dinic(s, INF);
	} writeln(maxflow);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

费用流

int ver[M], edge[M], cost[M], Next[M], head[N];
int dis[N], incf[N], pre[N]; bool vis[N];
int n, m, tot = 1, s, t, maxflow, mincost;

inline void add(int x, int y, int z, int c) {
	ver[++tot] = y, edge[tot] = z, cost[tot] = c;
	Next[tot] = head[x], head[x] = tot;
	ver[++tot] = x, edge[tot] = 0, cost[tot] = -c;
	Next[tot] = head[y], head[y] = tot;
}

namespace EK {

inline bool spfa(void) {
	queue <int> q; Ms(dis, 0x3f); Ms(vis, 0);
	q.push(s); dis[s] = 0; vis[s] = true; 
	incf[s] = INT_MAX;
	
	while (!q.empty()) {
		int x = q.front();
		vis[x] = 0; q.pop();
		for (int i = head[x]; i; i = Next[i]) {
			if (!edge[i]) continue;
			int y = ver[i];
			if (dis[y] > dis[x] + cost[i]) {
				dis[y] = dis[x] + cost[i];
				incf[y] = min(incf[x], edge[i]);
				pre[y] = i;
				if (!vis[y]) vis[y] = true, q.push(y);
			}
		}
	}
	
	if (dis[t] == 0x3f3f3f3f) return false;
	return true;
}

inline void update(void) {
	int x = t;
	while (x ^ s) {
		int i = pre[x];
		edge[i] -= incf[t];
		edge[i ^ 1] += incf[t];
		x = ver[i ^ 1];
	}
	maxflow += incf[t];
	mincost += dis[t] * incf[t];
}
}

signed main(void) {
	//file("");
	read(n); read(m); read(s); read(t);
	for (int i = 1, u, v, w, f; i <= m; i++) {
		read(u); read(v); read(w); read(f);
		add(u, v, w, f);
	}
	
	while (EK :: spfa()) EK :: update();
	writeln(maxflow, ' '); writeln(mincost);
	
    return 0;
}

manacher

const int Maxn = 2.2e7 + 5;
int n, cnt, p[Maxn], mxr, mid, ans;
char s[Maxn], t[Maxn];

signed main(void) {
	readstr(s + 1); n = strlen(s + 1); t[++cnt] = '@'; t[++cnt] = '#';
	for (int i = 1; i <= n; i++) t[++cnt] = s[i], t[++cnt] = '#'; t[++cnt] = '&';
	for (int i = 2; i < cnt; i++) {
		p[i] = i <= mxr ? min(p[mid * 2 - i], mxr - i + 1) : 1;
		while (t[i - p[i]] == t[i + p[i]]) ++p[i];
		if (i + p[i] - 1 >= mxr) mxr = i + p[i] - 1, mid = i;
		chkmax(ans, p[i] - 1);
	} writeln(ans);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

SAM

char str[Maxn];
int n, m, Rank[Maxn], SA[Maxn];
int cnt[Maxn], tmp[Maxn], Height[Maxn];

inline void GetStringData(void) {
	readstr(str + 1); m = 256;
	n = strlen(str + 1); return;
}

inline void RadixSort(void) {
	for (int i = 0; i <= m; i++) cnt[i] = 0;
	for (int i = 1; i <= n; i++) ++cnt[Rank[i]];
	for (int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
	for (int i = n; i >= 1; i--) SA[cnt[Rank[tmp[i]]]--] = tmp[i];
}

inline void SuffixSort(void) {
	for (int i = 1; i <= n; i++)
		Rank[i] = str[i], tmp[i] = i; RadixSort();
	for (int k = 1, tot = 0; tot < n; m = tot, k <<= 1) {
		tot = 0;
		for (int i = 1; i <= k; i++) tmp[++tot] = n - k + i;
		for (int i = 1; i <= n; i++) if (SA[i] > k) tmp[++tot] = SA[i] - k;
		RadixSort(); swap(tmp, Rank); Rank[SA[1]] = tot = 1;
		for (int i = 2; i <= n; i++)
			Rank[SA[i]] = (tmp[SA[i - 1]] == tmp[SA[i]] && tmp[SA[i - 1] + k] == tmp[SA[i] + k]) ? tot : ++tot;
	}
	for (register int i = 1, k = 0; i <= n; (i++)[Rank][Height] = k)
		for (k -= (k > 0); ((i[Rank] - 1)[SA] + k)[str] == (i + k)[str]; k++);
}

pair <int, int> minn[Maxn][21];
int logg[Maxn], ans;

inline pair <int, int> ST_query(int l, int r) {
	register int tnp = logg[r - l + 1]; 
	return min(minn[l][tnp], minn[r - (1 << tnp) + 1][tnp]);
}

inline void ST_init(void) {
	logg[0] = -1;
	for (register int i = 1; i <= n; i++)
		minn[i][0] = Mp(Height[i], i), logg[i] = logg[i >> 1] + 1;
	for (int j = 1; j <= 20; j++)
		for (int i = 1; i + (1 << j) - 1 <= n; i++)
    		minn[i][j] = min(minn[i][j - 1], minn[i + (1 << (j - 1))][j - 1]);
}

inline void Work(int l, int r) {
	if (l > r) return;
	pair <int, int> tnp = ST_query(l, r);
	ans = max(ans, tnp.first * (r - l + 2));
	Work(l, tnp.second - 1), Work(tnp.second + 1, r);
}

signed main(void) {
	//file("SuffixSort");
	GetStringData();
	SuffixSort(); ST_init();
	Work(1, n); writeln(ans);
	return 0;
}

ACAM


struct Node {
	int child[27], fail;
	inline int& operator [] (const int &idx) {return child[idx];}
} trie[Maxn];


int n, tot, que[Maxn], head, tail;
int d[Maxn], ans[Maxn], hd[Maxn], nxt[Maxn];
char str[Maxn * 10];

inline void Insert(char *s, int id) {
	int cur = 0, len = strlen(s);
	for (int i = 0; i < len; i++) {
		if (!trie[cur][s[i] - 'a'])
			trie[cur][s[i] - 'a'] = ++tot;
		cur = trie[cur][s[i] - 'a'];
	}
	nxt[id] = hd[cur]; hd[cur] = id;
}

inline void Build(void) {
	head = 1; tail = 0;
	for (int i = 0; i < 26; i++)
		if (trie[0][i]) que[++tail] = trie[0][i];
	while (head <= tail) {
		int top = que[head++];
		for (int i = 0; i < 26; i++)
			if (trie[top][i])
				trie[trie[top][i]].fail = trie[trie[top].fail][i]
				, que[++tail] = trie[top][i];
			else trie[top][i] = trie[trie[top].fail][i];
	}
}

inline void Solve(void) {
	readstr(str);
	int cur = 0, len = strlen(str);
	for (int i = 0; i < len; i++)
		cur = trie[cur][str[i] - 'a'], ++d[cur];
	for (int i = tot; i >= 1; i--) {
		for (int j = hd[que[i]]; j; j = nxt[j]) ans[j] = d[que[i]];
		d[trie[que[i]].fail] += d[que[i]];
	}
}

signed main(void) {
	//file("");
	read(n);
	for (int i = 1; i <= n; i++)
		readstr(str), Insert(str, i);
	Build(), Solve();
	for (int i = 1; i <= n; i++) writeln(ans[i]);
	return 0;
}

割点

const int Maxn = 2e4 + 5, Maxm = 2e5 + 5;
int n, m, cnt = 0, head[Maxn], ver[Maxm], nxt[Maxm];
inline void AddEdge(int u, int v) {
	ver[++cnt] = v, nxt[cnt] = head[u], head[u] = cnt;
	ver[++cnt] = u, nxt[cnt] = head[v], head[v] = cnt;
}

int dfn[Maxn], low[Maxn], timer = 0, root;
vector <int> ans; bool cut[Maxn];
inline void Tarjan(int u) {
	dfn[u] = low[u] = ++timer; int tot = 0;
	for (int i = head[u]; i; i = nxt[i])
		if (!dfn[ver[i]]) {
			Tarjan(ver[i]);
			chkmin(low[u], low[ver[i]]);
			if (dfn[u] <= low[ver[i]]) {
				++tot;
				if (u != root || tot > 1) cut[u] = true;
			}
		} else chkmin(low[u], dfn[ver[i]]);
}

signed main(void) {
//	file("");
	read(n), read(m);
	for (int i = 1, u, v; i <= m; i++)
		read(u), read(v), AddEdge(u, v);
	for (int i = 1; i <= n; i++) if (!dfn[i]) root = i, Tarjan(i);
	for (int i = 1; i <= n; i++) if (cut[i]) ans.push_back(i); writeln(ans.size());
	for (int i = 0; i < ans.size(); i++) writeln(ans[i], " \n"[i == ans.size() - 1]);
	return 0;
}

CDQ

const int Maxn = 1e5 + 5, Maxm = 2e5 + 5;
struct state {
	int x, y, z, same, cnt;
	state(void) { x = y = z = same = cnt = 0; }
	inline void Scanner(void) { read(x), read(y), read(z); }
	inline bool operator != (const state&rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z; }
} a[Maxn], b[Maxn];

inline bool cmp1(const state&p, const state&q) {
	if (p.x != q.x) return p.x < q.x;
	if (p.y != q.y) return p.y < q.y;
	return p.z < q.z;
}

inline bool cmp2(const state&p, const state&q) {
	if (p.y != q.y) return p.y < q.y;
	return p.z < q.z;
}

int n, k, tot = 0, ans[Maxn], c[Maxn];
inline void update(int pos, int val) {
	for (; pos <= k; pos += lowbit(pos)) c[pos] += val;
}

inline int query(int pos) {
	int ret = 0;
	for (; pos; pos -= lowbit(pos)) ret += c[pos];
	return ret;
}

inline void solve(int l, int r) {
	if (l == r) return;
	int mid = l + r >> 1, j = l;
	solve(l, mid), solve(mid + 1, r);
	sort(b + l, b + mid + 1, cmp2);
	sort(b + mid + 1, b + r + 1, cmp2);
	for (int i = mid + 1; i <= r; i++) {
		while (j <= mid && b[j].y <= b[i].y) update(b[j].z, b[j].same), j++;
		b[i].cnt += query(b[i].z);
	} for (int i = l; i < j; i++) update(b[i].z, -b[i].same); 
}

signed main(void) {
	read(n), read(k);
	for (int i = 1; i <= n; i++) a[i].Scanner();
	sort(a + 1, a + n + 1, cmp1);
	for (int i = 1, s = 1; i <= n; i++)
		if (a[i] != a[i + 1]) {
			b[++tot] = a[i]; b[tot].same = s; s = 1;
		} else ++s;
	solve(1, tot);
	for (int i = 1; i <= tot; i++) ans[b[i].same + b[i].cnt] += b[i].same;
	for (int i = 1; i <= n; i++) writeln(ans[i]);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

最小斯坦纳生成树

const int Maxn = 1e2 + 5; const int Maxm = 1e3 + 5;
int n, m, k, cnt = 0, head[Maxn], ver[Maxm], nxt[Maxm], edge[Maxm];
inline void AddEdge(int u, int v, int w) {
	ver[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt;
	ver[++cnt] = u, edge[cnt] = w, nxt[cnt] = head[v], head[v] = cnt;
} int p[Maxn], dp[Maxn][1 << 11]; bool vis[Maxn];

struct state {
	int u, d;
	state(void) { u = d = 0; }
	state(int _u, int _d) : u(_u), d(_d) {}
	inline bool operator < (const state&rhs) const { return d > rhs.d; }
}; priority_queue <state> q;

inline void Dijkstra(int s) {
	Ms(vis, false);
	while (!q.empty()) {
		int u = q.top().u; q.pop();
		if (vis[u]) continue; vis[u] = true;
		for (int i = head[u]; i; i = nxt[i]) {
			if (dp[ver[i]][s] > dp[u][s] + edge[i]) {
				dp[ver[i]][s] = dp[u][s] + edge[i];
				q.push(state(ver[i], dp[ver[i]][s]));
			}
		}
	}
}

signed main(void) {
//	file("");
	read(n), read(m), read(k); Ms(dp, 0x3f);
	for (int i = 1, u, v, w; i <= m; i++)
		read(u), read(v), read(w), AddEdge(u, v, w);
	for (int i = 1; i <= k; i++) read(p[i]), dp[p[i]][1 << i - 1] = 0;

	for (int s = 1; s < 1 << k; s++) {
		for (int i = 1; i <= n; i++) {
		for (int subset = s & (s - 1); subset; subset = (subset - 1) & s)
			chkmin(dp[i][s], dp[i][subset] + dp[i][subset ^ s]);
			if (dp[i][s] != 0x3f3f3f3f) q.push(state(i, dp[i][s]));
		} Dijkstra(s);
	} writeln(dp[p[1]][(1 << k) - 1]);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}
posted @   EternalEpic  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示