代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned int UIT;
typedef double DB;
typedef pair<int, int> PII;
#define fi first
#define se second
//--------------------//
//--------------------//
int main() {
return 0;
}
快读
inline int rd() {
int ret = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -f;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
ret = ret * 10 + ch - '0', ch = getchar();
return ret * f;
}
\(O(1)\) 求 LCA
int dcnt, dfn[N], lg[N], val[LG][N];
int get(int x, int y) {
return (dfn[x] < dfn[y] ? x : y);
}
void DFS(int now, int fa) {
val[0][dfn[now] = ++dcnt] = fa;
for (int i = head[now]; i; i = edge[i].nex)
if (edge[i].to != fa)
DFS(edge[i].to, now);
}
void init() {
for (int i = 2; i <= n; i++)
lg[i] = lg[i >> 1] + 1;
for (int i = 1; i <= lg[n]; i++)
for (int j = 1; j + (1 << i) - 1 <= n; j++)
val[i][j] = get(val[i - 1][j], val[i - 1][j + (1 << (i - 1))]);
}
int LCA(int u, int v) {
if(u == v)
return u;
if((u = dfn[u]) > (v = dfn[v]))
swap(u, v);
int d = lg[v - u++];
return get(val[d][u], val[d][v - (1 << d) + 1]);
}
最大流
struct Edge {
int to, nex;
LL c;
};
struct Flow {
Edge edge[M];
int tot = 1, head[N], cur[N], lev[N];
int S, T;
void add(int u, int v, int c) {
edge[++tot] = {v, head[u], c};
head[u] = tot;
edge[++tot] = {u, head[v], 0};
head[v] = tot;
}
LL DFS(int now, LL mnc) {
if (now == T)
return mnc;
LL res = 0;
for (int to, &i = cur[now]; i && mnc; i = edge[i].nex) {
LL toc = min(mnc, edge[i].c);
to = edge[i].to;
if (toc && lev[now] + 1 == lev[to]) {
LL tem = DFS(to, toc);
res += tem, mnc -= tem, edge[i].c -= tem, edge[i ^ 1].c += tem;
}
if (!mnc)
break;
}
if (!res)
lev[now] = -1;
return res;
}
LL work(int n) {
LL res = 0;
while (lev[T] != -1) {
for (int i = 1; i <= n; i++)
cur[i] = head[i], lev[i] = -1;
queue<int> q;
lev[S] = 0, q.push(S);
while (!q.empty()) {
int now = q.front(); q.pop();
for (int to, i = head[now]; i; i = edge[i].nex) {
to = edge[i].to;
if (edge[i].c && lev[to] == -1)
lev[to] = lev[now] + 1, q.push(to);
}
}
if (lev[T] != -1)
res += DFS(S, INT_MAX);
}
return res;
}
} F;
最小费用最大流
struct Edge {
int to, nex;
LL c, w;
};
struct Flow {
Edge edge[M];
int tot = 1, head[N], cur[N];
LL dis[N];
int S, T;
bool v[N];
void add(int u, int v, int c, int w) {
edge[++tot] = {v, head[u], c, w};
head[u] = tot;
edge[++tot] = {u, head[v], 0, -w};
head[v] = tot;
}
LL DFS(int now, LL mnc) {
if (now == T)
return mnc;
v[now] = true;
LL res = 0;
for (int to, &i = cur[now]; i && mnc; i = edge[i].nex) {
LL toc = min(mnc, edge[i].c);
to = edge[i].to;
if (!v[to] && toc && dis[now] + edge[i].w == dis[to]) {
LL tem = DFS(to, toc);
res += tem, mnc -= tem, edge[i].c -= tem, edge[i ^ 1].c += tem;
}
if (!mnc)
break;
}
if (!res)
dis[now] = 1e18;
v[now] = false;
return res;
}
queue<int> q;
pair<LL, LL> work(int n) {
LL resc = 0, resw = 0;
while (dis[T] != 1e18) {
for (int i = 1; i <= n; i++)
cur[i] = head[i], dis[i] = 1e18;
dis[S] = 0, q.push(S), v[S] = true;
while (!q.empty()) {
int now = q.front(); q.pop(), v[now] = false;
for (int to, i = head[now]; i; i = edge[i].nex) {
to = edge[i].to; LL w = edge[i].w;
if (edge[i].c && dis[to] > dis[now] + w) {
dis[to] = dis[now] + w;
if (!v[to])
v[to] = true, q.push(to);
}
}
}
if (dis[T] != 1e18) {
LL tem = DFS(S, INT_MAX);
resc += tem, resw += tem * dis[T];
}
}
return {resc, resw};
}
} F;
SAM
struct SAM {
struct SAM_Node {
int nex[30];
int fa, len, siz;
} s[N2];
int tot = 1, las = 1;
void ins(char ch) {
int it = ch - 'a' + 1, p = las, cur = ++tot;
s[cur].len = s[las].len + 1, las = cur, s[cur].siz = 1;
while (!s[p].nex[it] && p)
s[p].nex[it] = cur, p = s[p].fa;
if (!p)
return s[cur].fa = 1, void();
int q = s[p].nex[it];
if (s[p].len + 1 == s[q].len)
return s[cur].fa = q, void();
int cl = ++tot;
s[cl] = s[q], s[cl].siz = 0, s[cl].len = s[p].len + 1, s[cur].fa = s[q].fa = cl;
while (s[p].nex[it] == q && p)
s[p].nex[it] = cl, p = s[p].fa;
}
int bac[N], id[N2], ans[N];
void work(int n) {
for (int i = 1; i <= tot; i++)
bac[s[i].len]++;
for (int i = 1; i <= n; i++)
bac[i] += bac[i - 1];
for (int i = tot; i >= 1; i--)
id[bac[s[i].len]--] = i;
for (int i = tot; i >= 1; i--)
s[s[id[i]].fa].siz += s[id[i]].siz;
return;
}
} S;
组合数
int fac[N], invf[N];
int fast_pow(int x, int y) {
int res = 1;
while (y) {
if (y & 1)
res = 1LL * res * x % Mod;
x = 1LL * x * x % Mod;
y >>= 1;
}
return res;
}
int C(int n, int m) {
return ((n < 0 || m < 0 || n < m) ? 0 : 1LL * fac[n] * invf[n - m] % Mod * invf[m] % Mod);
}
void init(int n) {
for (int i = fac[0] = 1; i <= n; i++)
fac[i] = 1LL * fac[i - 1] * i % Mod;
invf[n] = fast_pow(fac[n], Mod - 2);
for (int i = n; i >= 1; i--)
invf[i - 1] = 1LL * invf[i] * i % Mod;
}
快速取模
int fmod(int x) {
return x >= Mod ? x - Mod : x;
}
void fadd(int &x, int y) {
x = fmod(x + y);
}
int fmod(int x, int Mod) {
return x >= Mod ? x - Mod : x;
}
void fadd(int &x, int y, int Mod) {
x = fmod(x + y, Mod);
}
矩阵
int msiz;
struct Mat {
int mat[MA][MA];
int *operator[](int x) {return mat[x];}
Mat() {memset(mat, 0, sizeof(mat));}
void init() {
for (int i = 1; i <= msiz; i++)
mat[i][i] = 1;
}
};
Mat operator*(Mat &a, Mat &b) {
Mat c;
for (int i = 1; i <= msiz; i++)
for (int j = 1; j <= msiz; j++)
for (int k = 1; k <= msiz; k++)
c[i][j] += a[i][k] * b[k][j];
return c;
}
Mat operator^(Mat x, int y) {
Mat res(msiz, msiz);
res.init();
while (y) {
if (y & 1)
res = res * x;
y >>= 1, x = x * x;
}
return res;
}
int msiz;
struct Mat {
int mat[MA][MA];
int *operator[](int x) {return mat[x];}
Mat() {memset(mat, 0, sizeof(mat));}
void init() {
for (int i = 1; i <= msiz; i++)
mat[i][i] = 1;
}
};
Mat operator*(Mat &a, Mat &b) {
Mat c;
for (int i =1; i <= msiz; i++)
for (int j = 1; j <= msiz; j++)
for (int k = 1; k <= msiz; k++)
fadd(c[i][j], 1LL * a[i][k] * b[k][j] % Mod);
return c;
}
Mat operator^(Mat x, int y) {
Mat res(msiz, msiz);
res.init();
while (y) {
if (y & 1)
res = res * x;
y >>= 1, x = x * x;
}
return res;
}
struct Mat {
int n, m, mat[MA][MA];
int *operator[](int x) {return mat[x];}
Mat() {memset(mat, 0, sizeof(mat));}
Mat(int tn, int tm) {
n = tn, m = tm;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
mat[i][j] = 0;
}
void init() {
for (int i = 1; i <= n; i++)
mat[i][i] = 1;
}
};
Mat operator*(Mat &a, Mat &b) {
Mat c(a.n, b.m);
for (int i = 1; i <= c.n; i++)
for (int j = 1; j <= c.m; j++)
for (int k = 1; k <= a.m; k++)
fadd(c[i][j], 1LL * a[i][k] * b[k][j] % Mod);
return c;
}
Mat operator^(Mat x, int y) {
Mat res(x.n, x.m);
res.init();
while (y) {
if (y & 1)
res = res * x;
y >>= 1, x = x * x;
}
return res;
}
快速幂
int fast_pow(int x, int y) {
int res = 1;
while (y) {
if (y & 1)
res = 1LL * res * x % Mod;
y >>= 1, x = 1LL * x * x % Mod;
}
return res;
}