板子大全
1.板子大全
数据结构
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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现