并没有力气写完了T_T
【数学】
- 快速幂/快速乘
int Pow(int a, int b, int Mod)
{
int temp = 1, cmp = a;
while (b) {
if (b & 1) temp = temp * cmp % Mod;
b >>= 1;
cmp = cmp * cmp % Mod;
}
return temp;
}
int Mul(int a, int b, int Mod)
{
int temp = 1, cmp = a;
while (b) {
if (b & 1) temp = (temp + cmp) % Mod;
b >>= 1;
cmp = (cmp + cmp) % Mod;
}
return temp;
}
- 矩阵快速幂
struct Mart {
int C[MartMax][MartMax];
int Mod;
Mart operator * (const Mart &b) const
{
Mart ans;
for (int i = 1; i <= MartMax; ++ i)
for (int j = 1; j <= MartMax; ++ j)
{
unsigned long long temp = 0llu;
for (int k = 1; k <= MartMax; ++ k)
temp += C[i][k] * b.C[k][j];
ans.C[i][j] = temp % Mod;
}
return ans;
}
}E;
Mart MartPow(Mart A, int b)
{
for (int i = 1; i <= MartMax; ++ i) E.C[i][i] = 1;
while (b) {
if (b & 1) E = E * A;
b >>= 1;
A = A * A;
}
return E;
}
- GCD
int gcd(int a, int b)
{
if (!a || !b) return a + b;
for (int t = a % b; b; a = b, b = t, t = a % b);
return b;
}
- 扩展欧几里得
void Ex_gcd(int a, int b, int &x, int &y)
{
if (!b) { x = 1, y = 0; return; }
Ex_gcd(b, a % b, y, x); y -= a / b * x;
}
- 线性筛欧拉函数
void get_phi()
{
phi[1] = 1;
for (int i = 2; i <= N; ++ i) {
if (!Mark[i]) {
prime[++ tot] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= tot && i * prime[j] <= N; ++ j) {
Mark[i * prime[j]] = 1;
if (i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
} else phi[i * prime[j]] = phi[i] * phi[prime[j]];
}
}
}
- 高斯消元
typedef double Matrix[Nmax][Nmax];
void Gauss(Matrix A, int N)
{
for (int i = 0; i < N; ++ i) {
int r = i;
for (int j = i + 1; j < N; ++ j) if (fabs(A[j][i]) > fabs(A[r][i])) r = j;
if (r ^ i) for (int j = 0; j <= N; ++ j) swap(A[r][j], A[i][j]);
for (int k = i + 1; k < N; ++ k) {
double f = A[k][i] / A[i][i];
for (int j = i; j <= N; ++ j) A[k][j] -= f * A[i][j];
}
for (int i = N - 1; ~i; -- i) {
for (int j = i + 1; j < N; ++ j)
A[i][N] -= A[j][N] * A[i][j];
A[i][N] /= A[i][i];
}
【图论】
- SPFA
int dis[Nmax];
bool vis[Nmax];
queue <int> q;
int spfa(int S, int T)
{
memset(dis, 0x3f, sizeof(dis));
q.push(S); dis[S] = 0;
while (q.size()) {
int u = q.front(); q.pop(); vis[u] = 0;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (dis[v] > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
if (!vis[v]) { vis[v] = 1; q.push(v); }
}
}
}
return dis[T];
}
- Dijkstra
typedef pair<int, int> node;
priority_queue < node, vector<node>, greater<node> > q;
int dis[Nmax];
int dijkstra(int S, int T)
{
memset(dis, 0x3f, sizeof(dis));
q.push(node(0, S));
while (q.size()) {
node temp = q.top(); q.pop();
int u = temp.second;
if (temp.first != dis[u]) continue;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (dis[v] > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
q.push(node(dis[v], v));
}
}
}
return dis[T];
}
- Floyd最小环
int map[Nmax][Nmax], dis[Nmax][Nmax];
int floyd()
{
int MinCircle = inf;
for (int k = 1; k <= N; ++ k) {
for (int i = 1; i <= N; ++ i)
for (int j = 1; j <= N; ++ j)
MinCircle = min(MinCircle, dis[i][j] + map[i][k] + map[k][j]);
for (int i = 1; i <= N; ++ i)
for (int j = 1; j <= N; ++ j)
dis[i][j] = min(dis[i][k] + dis[k][j]);
}
return MinCircle;
}
- Kruskal
int f[Nmax];
int find(int x) { return (x == f[x]) ? x : f[x] = find(f[x]); }
bool cmp(ed &a, ed &b) { return a.w < b.w; }
int kruskal(int N, int M)
{
for (int i = 1; i <= N; ++i) f[i] = i;
sort(e + 1, e + M + 1, cmp);
int ans = 0;
for (int i = 1; i <= M; ++i) {
int u = e[i].u, v = e[i].v;
int fu = find(u), fv = find(v);
if (fu == fv) continue;
f[fu] = fv; ans += e[i].w;
}
return ans;
}
- Prim
int dis[Nmax], map[Nmax][Nmax], N;
bool vis[Nmax];
int prim()
{
int sum = 0;
for (int i = 1; i <= N; ++ i) dis[i] = map[1][i];
vis[1] = 1;
for (int i = 1; i < N; ++ i) {
int pos = -1, mmin = inf;
for (int j = 1; j <= N; ++ i) {
if (!vis[j] && dis[j] < mmin){
pos = j; mmin = dis[j];
}
}
if (pos == -1) break;
vis[pos] = 1; sum += dis[pos];
for (int j = 1; j <= N; ++ i) dis[j] = map[pos][j];
}
return sum;
}
- LCA
int dep[Nmax], d[Nmax];
int f[Nmax][20];
void dfs(int u, int fa, int w)
{
dep[u] = dep[fa] + 1, d[u] = d[fa] + w;
f[u][0] = fa;
for (int i = 1; (1 << i) <= dep[u]; ++ i) f[u][i] = f[f[u][i - 1]][i - 1];
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (v != fa) dfs(v, u, e[i].w);
}
}
int LCA(int u, int v)
{
if (dep[u] < dep[v]) swap(u, v);
int k = dep[u] - dep[v];
for (int i = 1; (1 << i) <= dep[u]; ++ i) if (k & (1 << i)) u = f[u][i];
if (u == v) return u;
else for (int i = 19; ~i; -- i)
if (f[u][i] != f[v][i]) { u = f[u][i]; v = f[v][i]; }
return f[u][0];
}
- Tarjan强联通
int dfn[Nmax], low[Nmax];
int belong[Nmax];
int tot, scnt;
stack <int> s;
bool ins[Nmax];
void dfs(int u)
{
dfn[u] = low[u] = ++ tot;
s.push(u); ins[u] = 1;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (!dfn[v]) { dfs(v); low[u] = min(low[v], low[u]); }
else if (ins[v]) low[u] = min(low[v], low[u]);
}
if (low[u] == dfn[u]) {
++ scnt;
for ( ; ; ) {
int v = s.top(); s.pop();
belong[v] = scnt;
if (v == u) break;
}
}
}
- 匈牙利算法
int map[Nmax][Nmax];
int cx, cy;
int match[Nmax];
bool Vis[Nmax];
bool Match(int u)
{
for (int v = 1; v < cy; ++v) {
if (!map[u][v] || Vis[v]) continue;
Vis[v] = 1;
if (match[v] == -1 || Match(match[v])) {
match[v] = u; return 1;
}
}
return 0;
}
int Hurngray()
{
memset(match, -1, sizeof(match));
int res = 0;
for (int i = 1; i <= cx; ++i) {
memset(vis, 0, sizeof(vis));
res += Match(i);
}
return res;
}
- KM
int N;
int w[Nmax][Nmax];
int lx[Nmax], ly[Nmax], match[Nmax], slack[Nmax];
bool visx[Nmax], visy[Nmax];
bool dfs(int u)
{
visx[u] = 1;
for (int v = 1; v <= N; ++ v) if(!visy[v]){
int t = lx[u] + ly[v] - w[u][v];
if (!t) {
visy[v] = 1;
if (match[v] == -1 || dfs(match[v])) {
match[v] = u; return 1;
}
else if (slack[v] > t) slack[v] = t;
}
}
return 0;
}
void adjust()
{
int d = inf;
for (int i = 1; i <= N; ++ i) if (!visy[i] && slack[i] < d) d = slack[i];
for (int i = 1; i <= N; ++ i) if (visx[i]) lx[i] -= d;
for (int i = 1; i <= N; ++ i) if (visy[i]) ly[i] += d; else slack[i] -= d;
}
int KM()
{
memset(match, -1, sizeof(match));
memset(ly, 0, sizeof(ly));
for (int i = 1; i <= N; ++ i) {
lx[i] = -inf;
for (int j = 1; j <= N; ++ j) if (w[i][j] > lx[i])
lx[i] = w[i][j];
}
for (int i = 1; i <= N; ++ i) {
for (int j = 1; j <= N; ++ j) slack[j] = inf;
for ( ; ; ) {
memset(visx, 0, sizeof(visx));
memset(visy, 0, sizeof(visy));
if (dfs(i)) break;
else adjust();
}
}
int ans = 0;
for (int i = 1; i <= N; ++ i) ans += w[match[i]][i];
return ans;
}
- Dinic
int S, T;
queue <int> q;
int dis[Nmax];
bool bfs()
{
memcpy(cur, head, sizeof(cur));
memset(dis, -1, sizeof(dis));
while (q.size()) q.pop(); q.push(S); dis[S] = 0;
while (q.size()) {
int u = q.front(); q.pop();
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (e[i].flow && dis[v] == -1) {
dis[v] = dis[u] + 1;
if (v == T) return 1;
q.push(v);
}
}
}
return 0;
}
int dfs(int u, int maxf)
{
if (u == T || !maxf) return maxf;
int flow = 0, f;
for (int &i = cur[u]; i; i = e[i].next) {
int v = e[i].v;
if (dis[v] == dis[u] + 1 && (f = dfs(v, min(maxf, e[i].w))) > 0) {
e[i].flow -= f; e[i ^ 1].flow -= f;
flow += f; maxf -= f; if (!maxf) break;
}
}
return flow;
}
int max_flow()
{
int f = 0;
while (bfs()) f += dfs(S, inf);
return f;
}
- 费用流 (SPFA没力气写了 TAT)
int MinCostMaxFlow()
{
int cost = 0;
while (spfa()) {
for (int i = T; i != S; i = e[pre[i] ^ 1].v) {
e[pre[i]].flow -= deltaf;
e[pre[i] ^ 1].flow += deltaf;
}
cost += deltaf * dis[T];
}
}
【数据结构】
- 树状数组
#define lowbit(x) (x & -x)
namespace BIT {
int sum[Nmax][2];
inline void Add(bool s, int pos, int c)
{
for (int i = pos; i <= N; i += lowbit(i))
sum[i][s] += c;
}
inline int Sum(bool s, int pos)
{
int res = 0;
for (int i = pos; i; i -= lowbit(i))
res += sum[i][s];
return res;
}
inline void Modify(int l, int r, int c)
{
Add(0, l, c); Add(1, l, l * c);
Add(0, r + 1, -c); Add(1, r + 1, -(r + 1) * c);
}
inline int Query(int l, int r)
{
int temp = (r + 1) * Sum(0, r) - Sum(1, r);
temp -= l * Sum(0, l - 1) - Sum(1, l - 1);
return temp;
}
}
namespace Splay {
struct node {
node *c[2], *f;
int w, size, mmin;
int add, rev;
inline bool right() { return f -> c[1] == this; }
inline void setch(node *p, bool r) { c[r] = p; p -> f = this; }
};
void build(node *p, int l, int r, int rank)
{
p -> w = p -> mmin = a[rank];
if (l ^ rank) {
node *lch = NewNode();
p -> setch(lch, 0);
build(lch, l, rank - 1, (l + rank - 1) << 1);
}
if (r ^ rank) {
node *rch = NewNode();
p -> setch(rch, 1);
build(rch, rank + 1, r, (rank + 1 + r) << 1);
}
pushup(p);
}
void rotate(node *p)
{
node *fa = p -> f; bool r = p -> right();
fa -> f -> setch(p, f -> right());
fa -> setch(p -> c[r ^ 1], r);
p -> setch(fa, r ^ 1);
pushup(fa);
}
void splay(node *p, node *father)
{
while (p -> f != father) {
if (p -> f -> f == father) rotate(p);
else {
rotate(p -> right() == p -> f -> right() ? p -> fa : p);
rotate(p);
}
}
pushup(p);
if (p -> f == null) root = p;
}
node *find(int rank)
{
for (node *p = root; ; ) {
pushdown(p);
int ls = p -> lc -> s;
if (rank <= ls) p = p -> lc;
else if (rank + 1 == ls) return p;
else {
rank -= ls + 1;
p = p -> rc;
}
}
}
node *getrange(int l, int r)
{
-- l, ++ r;
splay(find(l), null); splay(find(r), root);
return root -> rc -> lc;
}
}
【字符串】
- KMP
int next[Nmax];
void KMP(char *str)
{
next[0] = next[1] = 0; int j = 0;
for (int i = 2; str[i]; ++ i) {
while (j && s[i] != s[j + 1]) j = next[j];
if (s[i] == s[j + 1]) ++ j; next[i] = j;
}
}
- Manacher
int far = 0, ans = 0;
for (int i = 1; s[i]; ++i) {
int already = p[far] + far;
p[i] = already > i ? min(already - i, p[(far << 1) - i]) : 1;
while (s[i - p[i]] == s[i + p[i]]) ++p[i];
if (i + p[i] >= already) far = i; ans = max(ans, p[i] - 1);
}
- 扩展KMP
inline void e_kmp()
{
int j = 0, last = 1;
for(; j < len && s[j] == s[j + 1]; ++j);
p[0] = len; p[1] = j;
for(int i = 2; i < len; ++i)
{
int itmax = p[i - last], already = max(0, last + p[last] - i);
if(itmax < already) p[i] = itmax;
else
{
p[i] = already; last = i;
while(i + p[i] < len && s[i + p[i]] == s[p[i]]) ++p[i];
}
}
}