算法模板
Abstract
记录一些自己写的算法模板,防止重复造轮子。
图论
邻接表
Code
namespace graph
{
int n;
const int maxn = 10000000;
int head[maxn];
int cnt;
struct Edge
{
int next, to, value;
} edge[maxn];
void add(int u, int v, int c)
{
edge[++cnt].next = head[u];
edge[cnt].to = v;
edge[cnt].value = c;
head[u] = cnt;
return;
}
void init()
{
cnt = 0;
for (int i = 0; i <= n; i++)
{
head[i] = 0;
}
return;
}
};
线性数据结构
线段树(区间最值,区间和)
Code
namespace seg
{
const int N = 1e6 + 1000;
struct Node
{
int sum, l, r, tag, min;
} nodes[N << 2];
#define l(x) (x << 1)
#define r(x) (x << 1 | 1)
void up(int rt)
{
nodes[rt].sum = nodes[l(rt)].sum + nodes[r(rt)].sum;
nodes[rt].min = min(nodes[l(rt)].min, nodes[r(rt)].min);
return;
}
void down(int rt)
{
int mid = nodes[rt].l + nodes[rt].r >> 1;
if (nodes[rt].tag)
{
nodes[l(rt)].tag += nodes[rt].tag, nodes[r(rt)].tag += nodes[rt].tag;
nodes[l(rt)].sum += nodes[rt].tag * (mid - nodes[l(rt)].l + 1);
nodes[r(rt)].sum += nodes[rt].tag * (nodes[r(rt)].r - mid);
nodes[l(rt)].min += nodes[rt].tag;
nodes[r(rt)].min += nodes[rt].tag;
nodes[rt].tag = 0;
}
return;
}
void build(int rt, int l, int r)
{
nodes[rt].l = l, nodes[rt].r = r;
nodes[rt].tag = 0;
if (l == r)
{
std::cin >> nodes[rt].sum;
nodes[rt].min = nodes[rt].sum;
return;
}
int mid = l + r >> 1;
build(l(rt), l, mid);
build(r(rt), mid + 1, r);
up(rt);
return;
}
void plus(int rt, int ql, int qr, int k)
{
int l = nodes[rt].l, r = nodes[rt].r;
if (ql <= l && r <= qr)
{
nodes[rt].tag += k;
nodes[rt].sum += k * (r - l + 1);
nodes[rt].min += k;
return;
}
int mid = l + r >> 1;
down(rt);
if (ql <= mid)
{
plus(l(rt), ql, qr, k);
}
if (mid + 1 <= qr)
{
plus(r(rt), ql, qr, k);
}
up(rt);
return;
}
int query(int rt, int ql, int qr)
{
int l = nodes[rt].l, r = nodes[rt].r;
if (ql <= l && r <= qr)
{
return nodes[rt].sum;
}
int mid = l + r >> 1;
int res = 0;
down(rt);
if (ql <= mid)
{
res += query(l(rt), ql, qr);
}
if (qr >= mid + 1)
{
res += query(r(rt), ql, qr);
}
return res;
}
};
数学
线性代数
矩阵的基本运算
Code
template <typename T>
struct Mat
{
int n, m;
T **a;
Mat(int _n = 0, int _m = 0) : n(_n), m(_m)
{
a = new T *[n];
for (int i = 0; i < n; i++)
a[i] = new T[m], memset(a[i], 0, sizeof(T) * m);
}
Mat(const Mat &B)
{
n = B.n, m = B.m;
a = new T *[n];
for (int i = 0; i < n; i++)
a[i] = new T[m], memcpy(a[i], B.a[i], sizeof(T) * m);
}
~Mat() { delete[] a; }
Mat &operator=(const Mat &B)
{
delete[] a;
n = B.n, m = B.m;
a = new T *[n];
for (int i = 0; i < n; i++)
a[i] = new T[m], memcpy(a[i], B.a[i], sizeof(T) * m);
return *this;
}
Mat operator+(const Mat &B) const
{ // 矩阵加法。
assert(n == B.n && m == B.m);
Mat ret(n, m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
ret.a[i][j] = (a[i][j] + B.a[i][j]) % mod;
return ret;
}
Mat &operator+=(const Mat &B) { return *this = *this + B; }
Mat operator*(const Mat &B) const
{
Mat ret(n, B.m);
for (int i = 0; i < n; ++i)
for (int j = 0; j < B.m; ret.a[i][j++] %= mod)
for (int k = 0; k < m; ++k)
ret.a[i][j] += a[i][k] * B.a[k][j] % mod;
return ret;
}
Mat &operator*=(const Mat &B) { return *this = *this * B; }
};
Mat<int> qpow(Mat<int> A, int b)
{
Mat<int> ret(A);
for (--b; b; b >>= 1, A *= A)
if (b & 1)
ret *= A;
return ret;
}
基础算法
高精度
Code
struct Num
{
std::vector<int> v;
void print()
{
for (int i = v[0]; i > 0; i--)
{
std::cout << v[i];
}
return;
}
void scan()
{
std::string t;
std::cin >> t;
int len = t.length();
v.resize(len + 1, 0);
for (int i = 0; i < len; i++)
{
v[len - i] = t[i] - '0';
}
v[0] = len;
return;
}
Num operator+(const Num &rhs) const
{
Num result;
result.v.resize(std::max(v[0], rhs.v[0]) + 2, 0);
result.v[0] = std::max(v[0], rhs.v[0]) + 1;
for (int i = 1; i <= result.v[0]; i++)
{
if (i <= v[0])
{
result.v[i] += v[i];
}
if (i <= rhs.v[0])
{
result.v[i] += rhs.v[i];
}
result.v[i + 1] += result.v[i] / 10;
result.v[i] %= 10;
}
while (result.v[result.v[0]])
{
result.v.push_back(result.v[result.v[0]] / 10);
result.v[result.v[0]] %= 10;
result.v[0]++;
}
while (result.v[result.v[0]] == 0 && result.v[0] > 1)
{
result.v[0]--;
}
return result;
}
Num operator*(const Num &rhs) const
{
Num result;
result.v.resize(v[0] + rhs.v[0] + 1, 0);
result.v[0] = v[0] + rhs.v[0];
for (int i = 1; i <= v[0]; i++)
{
for (int j = 1; j <= rhs.v[0]; j++)
{
result.v[i + j - 1] += rhs.v[j] * v[i];
result.v[i + j] += result.v[i + j - 1] / 10;
result.v[i + j - 1] %= 10;
}
}
while (result.v[result.v[0]])
{
result.v.push_back(result.v[result.v[0]] / 10);
result.v[result.v[0]] %= 10;
result.v[0]++;
}
while (result.v[result.v[0]] == 0 && result.v[0] > 1)
{
result.v[0]--;
}
return result;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步