模板集合
I.数学
1.快速幂
点击查看代码
int qpow(int a, int b, int mod){
int res = 1;
for (; b; a = a * a % mod, b >>= 1)
if (b & 1) res = res * a % mod;
return res % mod;
}
2.快速乘
点击查看代码
int qmul(int a, int b){
int res = 0;
for (; b; a = (a << 1) % mod, b >>= 1)
if (b & 1) res = (res + a) % mod;
return res % mod;
}
3.线性筛
第一种(\(v_i=0/1\) 表示 \(i\) 是否是质数)
点击查看代码
for (int i = 2; i <= n; i++){
if (!v[i]) p[++cnt] = i;
for (int j = 1; p[j] * i <= n; j++){
v[p[j] * i] = 1;
if (i % p[j] == 0) break;
}
}
第二种(\(v_i\) 表示 \(i\) 的最小质因子)
点击查看代码
for (int i = 2; i <= n; i++){
if (!v[i]) p[++cnt] = i, v[i] = i;
for (int j = 1; j <= cnt; j++){
if (p[j] > v[i] || p[j] > n / i) break;
v[p[j] * i] = p[j];
}
}
4.线性求逆元
点击查看代码
inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = (mod - mod / i) * inv[mod % i] % mod;
5.线性求欧拉函数
点击查看代码
void euler(int n){
for (int i = 2; i <= n; ++i){
if (!v[i]) v[i] = i, p[++cnt] = i, phi[i] = i - 1;
for (int j = 1; j <= cnt; ++j){
if (p[j] > v[i] || p[j] > n / i) break;
v[i * p[j]] = p[j], phi[i * p[j]] = phi[i] * (i % p[j] ? p[j] - 1 : p[j]);
}
}
}
6.exgcd
点击查看代码
void exgcd(int a, int b, int &x, int &y){
if (!b){
x = 1, y = 0;
return ;
}
exgcd(b, a % b, x, y);
int t = x;
x = y, y = t - a / b * y;
return ;
}
7.CRT
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 20;
int n, x, M = 1, a[N], b[N], m[N], u[N], v[N];
inline int read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
void exgcd(int a, int b, int &x, int &y){
if (!b){
x = 1, y = 0;
return ;
}
exgcd(b, a % b, x, y);
int t = x;
x = y, y = t - a / b * y;
return ;
}
signed main(){
n = read();
for (int i = 1; i <= n; ++i) b[i] = read(), a[i] = read(), M *= b[i];
for (int i = 1; i <= n; ++i) m[i] = M / b[i];
for (int i = 1; i <= n; ++i) exgcd(m[i], b[i], u[i], v[i]);
for (int i = 1; i <= n; ++i) x = (x + u[i] * a[i] * m[i] % M) % M;
printf("%lld\n", (x + M) % M);
return 0;
}
8.exCRT
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, a, b, x, lcm;
bool flag;
inline int read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
int qmul(int a, int b, int mod, int res = 0){
for (; b; b >>= 1, a = (a << 1) % mod)
if (b & 1) res = (res + a) % mod;
return res;
}
int exgcd(int a, int b, int &x, int &y){
if (!b){
x = 1, y = 0;
return a;
}
int gcd = exgcd(b, a % b, x, y), t = x;
x = y, y = t - a / b * y;
return gcd;
}
signed main(){
n = read(), b = read(), a = read(), lcm = b, x = a;
for (int i = 1, d, t1, t2, k; i < n; ++i){
b = read(), a = (read() - x % b + b) % b, d = exgcd(lcm, b, t1, t2);
if (a % d) flag = 1;
else k = qmul(t1, a / d, b);
x += k * lcm, lcm = lcm / d * b, x = (x % lcm + lcm) % lcm;
}
if (flag) puts("-1");
else printf("%lld\n", x);
return 0;
}
9.BSGS
点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a, b, p, ans;
int qpow(int a, int b, int mod, int res = 1){
for (; b; b >>= 1, a = a * a % mod)
if (b & 1) res = res * a % mod;
return res % mod;
}
int BSGS(int a, int b, int p, int t = 0){
map < int, int > Hash;
Hash.clear(), b %= p, t = (int)sqrt(p) + 1;
for (int j = 0, val; j < t; ++j) val = b * qpow(a, j, p) % p, Hash[val] = j;
a = qpow(a, t, p);
if (!a) return b == 0 ? 1 : -1;
for (int i = 0, j, val; i <= t; ++i){
val = qpow(a, i, p), j = Hash.find(val) == Hash.end() ? -1 : Hash[val];
if (j >= 0 && i * t - j >= 0) return i * t - j;
}
return -1;
}
signed main(){
scanf("%lld %lld %lld", &a, &b, &p), ans = BSGS(a, b, p);
if (ans != -1) printf("%lld\n", ans);
else puts("no solution");
return 0;
}
10.Lucas
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define N 200010
using namespace std;
int fac[N] = {1}, inv[N];
inline int read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
int qpow(int a, int b, int mod, int res = 1){
for (; b; b >>= 1, a = a * a % mod)
if (b & 1) res = res * a % mod;
return res % mod;
}
int C(int n, int m, int p){return m > n ? 0 : (fac[n] * inv[m] % p * inv[n - m] % p);}
int Lucas(int n, int m, int p){return !m ? 1 : ((C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p));}
signed main(){
for (int _ = read(), n, m, p; _--; ){
n = read(), m = read(), p = read();
for (int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i % p;
inv[min(n, p - 1)] = qpow(fac[min(n, p - 1)], p - 2, p);
for (int i = min(n - 1, p - 2); ~i; --i) inv[i] = inv[i + 1] * (i + 1) % p;
for (int i = p; i <= n; i++) inv[i] = 0;
printf("%lld\n", Lucas(n, m, p));
}
return 0;
}
11.高斯消元
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define N 110
using namespace std;
int n;
double a[N][N], ans[N];
inline int read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
signed main(){
n = read();
for (int i = 1; i <= n; ++i)
for (int j = 1; j < n + 2; ++j) scanf("%lf", &a[i][j]);
for (int i = 1; i <= n; ++i){
int t = 0;
for (int j = i; j <= n; ++j)
if (a[j][i]){
t = j;
break;
}
if (a[i][i] == 0){
puts("No Solution");
exit(0);
}
for (int j = 1; j < n + 2; ++j) swap(a[i][j], a[t][j]);
for (int j = i + 1; j <= n; ++j){
double l = a[j][i] / a[i][i];
for (int k = i; k <= n + 1; ++k) a[j][k] -= a[i][k] * l;
}
}
for (int i = n; i > 0; --i){
ans[i] = a[i][n + 1] / a[i][i];
for (int j = i - 1; j > 0; --j){
double l = a[j][i] / a[i][i];
for (int k = 1; k <= n + 1; ++k) a[j][k] -= a[i][k] * l;
}
}
for (int i = 1; i <= n; ++i) printf("%.2f\n", ans[i]);
return 0;
}
12.封装矩阵
点击查看代码
const int p = 1e9 + 7;
struct Matrix{
int n, m;
vector < vector < int > > a;
Matrix(int _n = 0, int _m = 0){
n = _n, m = _m;
if (!m){
m = n;
a = vector < vector < int > > (n + 1, vector < int > (m + 1));
for (int i = 1; i <= n; ++i) a[i][i] = 1;
}
else a = vector < vector < int > > (n + 1, vector < int > (m + 1));
}
vector <int >& operator[](int x) &{return a[x];}
const vector < int >& operator[](int x) const&{return a[x];}
inline int Read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
void read(){
a = vector < vector < int > > (n + 1, vector < int > (m + 1));
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) a[i][j] = Read();
}
inline void Write(int x){
if (x < 0) putchar('-'), x = -x;
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
return ;
}
void write(){
for (int i = 1; i <= n; ++i, puts(""))
for (int j = 1; j <= m; ++j) Write(a[i][j]), putchar(' ');
}
Matrix operator + (const Matrix b) const{
if (!(n == b.n && m == b.m)){
puts("No Solution");
exit(0);
}
Matrix res(n, m);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) res[i][j] = (a[i][j] + b[i][j]) % p;
return res;
}
Matrix operator - (const Matrix b) const{
if (!(n == b.n && m == b.m)){
puts("No Solution");
exit(0);
}
Matrix res(n, m);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) res[i][j] = (a[i][j] - b[i][j] + p) % p;
return res;
}
Matrix operator * (const int x) const{
Matrix res(n, m);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) res[i][j] = 1ll * a[i][j] * x % p;
return res;
}
Matrix operator * (const Matrix b) const{
if (m != b.n){
puts("No Solution");
exit(0);
}
Matrix res(n, b.m);
for (int i = 1; i <= n; ++i)
for (int k = 1; k <= m; ++k)
for (int j = 1; j <= b.m; ++j) res[i][j] = (res[i][j] + 1ll * a[i][k] * b[k][j] % p) % p;
return res;
}
Matrix operator ^ (int x) const{
if (!(n == m || x < 2)){
puts("No Solution");
exit(0);
}
Matrix res(m), a = *this;
for (; x; x >>= 1, a *= a)
if (x & 1) res *= a;
return res;
}
Matrix operator += (const Matrix b){return *this = *this + b;}
Matrix operator -= (const Matrix b){return *this = *this - b;}
Matrix operator *= (const int x){return *this = *this * x;}
Matrix operator *= (const Matrix b){return *this = *this * b;}
Matrix operator ^= (const int x){return *this = *this ^ x;}
bool operator == (const Matrix b) const{
if (n != b.n || m != b.m) return 0;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
if (a[i][j] != b[i][j]) return 0;
return 1;
}
bool operator != (const Matrix b) const{return !(*this == b);}
int ksm(int a, int b, int p, int res = 1){
for (; b; b >>= 1, a = 1ll * a * a % p)
if (b & 1) res = 1ll * res * a % p;
return res % p;
}
Matrix inv(){//楂樻柉娑堝厓
Matrix x = *this, y(n);
for (int i = 1; i <= n; ++i){
int pos = i;
for (int j = i + 1; j <= n; ++j)
if (abs(x[j][i]) > abs(x[pos][i])) pos = j;
if (pos != i) swap(x[i], x[pos]), swap(y[i], y[pos]);
if (!x[i][i]){
puts("No Solution");
exit(0);
}
int t = ksm(x[i][i], p - 2, p);
for (int j = 1; j <= n; ++j){
if (j == i) continue;
int l = 1ll * t * x[j][i] % p;
for (int k = 1; k <= n; ++k) x[j][k] = ((x[j][k] - 1ll * l * x[i][k] % p) % p + p) % p, y[j][k] = ((y[j][k] - 1ll * l * y[i][k] % p) % p + p) % p;
}
for (int j = 1; j <= n; ++j) x[i][j] = 1ll * x[i][j] * t % p, y[i][j] = 1ll * y[i][j] * t % p;
}
return y;
}
Matrix operator / (const int x){
Matrix res(n, m);
int t = ksm(x, p - 2, p);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) res[i][j] = 1ll * a[i][j] * t % p;
return res;
}
Matrix operator / (Matrix b) const{
b = b.inv();
if (m != b.n){
puts("No Solution");
exit(0);
}
Matrix res(n, b.m);
for (int i = 1; i <= n; ++i)
for (int k = 1; k <= m; ++k)
for (int j = 1; j <= b.m; ++j) res[i][j] = (res[i][j] + 1ll * a[i][j] * b[k][j] % p) % p;
return res;
}
Matrix operator /= (const int x){return *this = *this / x;}
Matrix operator /= (const Matrix b){return *this = *this / b;}
};
II.数据结构
III.字符串
IV.图论
1.Dijkstra
点击查看代码
void dijkstra(){
memset(dis, 0x3f, sizeof(dis));
dis[s] = 0, q.push({0, s});
while (!q.empty()){
int x = q.top().second;q.pop();
if (vis[x]) continue;
vis[x] = 1;
for (int i = head[x]; i; i = e[i].nxt){
int y = e[i].to, z = e[i].value;
if (dis[y] > dis[x] + z) dis[y] = dis[x] + z, q.push({-dis[y], y});
}
}
}
2.轻重链剖分
点击查看代码
const int N = 1e5 + 10;
int n, m, cnt, mod, tot, root, a[N], fa[N], rk[N], sz[N], dep[N], dfn[N], son[N], top[N], head[N];
struct xcj{
int to, nxt;
} e[N << 1];
struct xcx{
int l, r, sum, tag;
#define lp p << 1
#define rp p << 1 | 1
#define l(p) t[p].l
#define r(p) t[p].r
#define sum(p) t[p].sum
#define tag(p) t[p].tag
} t[N << 2];
inline int read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
void add(int u, int v){e[++cnt] = {v, head[u]}, head[u] = cnt;}
void build(int p, int l, int r){
l(p) = l, r(p) = r;
if (l == r){
sum(p) = a[rk[l]];
return ;
}
int mid = (l + r) >> 1;
build(lp, l, mid), build(rp, mid + 1, r), sum(p) = (sum(lp) + sum(rp)) % mod;
}
void spread(int p){
if (!tag(p)) return ;
tag(lp) += tag(p), tag(rp) += tag(p), sum(lp) = (sum(lp) + tag(p) * (r(lp) - l(lp) + 1) % mod) % mod, sum(rp) = (sum(rp) + tag(p) * (r(rp) - l(rp) + 1) % mod) % mod, tag(p) = 0;
}
void change(int p, int l, int r, int val){
if (l <= l(p) && r(p) <= r){
sum(p) = (sum(p) + val * (r(p) - l(p) + 1) % mod) % mod, tag(p) += val;
return ;
}
spread(p);
int mid = (l(p) + r(p)) >> 1;
if (l <= mid) change(lp, l, r, val);
if (r > mid) change(rp, l, r, val);
sum(p) = (sum(lp) + sum(rp)) % mod;
}
int ask(int p, int l, int r){
if (l <= l(p) && r(p) <= r) return sum(p);
spread(p);
int mid = (l(p) + r(p)) >> 1, res = 0;
if (l <= mid) res = ask(lp, l, r);
if (r > mid) res = (res + ask(rp, l, r)) % mod;
return res;
}
void dfs1(int x){
sz[x] = 1, son[x] = -1;
for (int i = head[x]; i; i = e[i].nxt){
int y = e[i].to;
if (dep[y]) continue;
dep[y] = dep[x] + 1, fa[y] = x, dfs1(y), sz[x] += sz[y];
if (!~son[x] || sz[y] > sz[son[x]]) son[x] = y;
}
}
void dfs2(int x, int top_x){
top[x] = top_x, dfn[x] = ++tot, rk[tot] = x;
if (!~son[x]) return ;
dfs2(son[x], top_x);
for (int i = head[x]; i; i = e[i].nxt){
int y = e[i].to;
if (y != fa[x] && y != son[x]) dfs2(y, y);
}
}
void change1(int x, int y, int z){
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap(x, y);
change(1, dfn[top[x]], dfn[x], z), x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
change(1, dfn[x], dfn[y], z);
}
int ask1(int x, int y, int res = 0){
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap(x, y);
res = (res + ask(1, dfn[top[x]], dfn[x])), x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
return (res + ask(1, dfn[x], dfn[y])) % mod;
}
void change2(int x, int y){change(1, dfn[x], dfn[x] + sz[x] - 1, y);}
int ask2(int x){return ask(1, dfn[x], dfn[x] + sz[x] - 1);}
signed main(){
n = read(), m = read(), root = read(), mod = read();
for (int i = 1; i <= n; ++i) a[i] = read();
for (int i = 1, u, v; i < n; ++i) u = read(), v = read(), add(u, v), add(v, u);
dep[root] = 1, dfs1(root), dfs2(root, root), build(1, 1, n);
for (int opt, x, y, z; m--; ){
opt = read(), x = read();
if (opt < 2) y = read(), z = read(), change1(x, y, z % mod);
else if (opt < 3) y = read(), printf("%d\n", ask1(x, y));
else if (opt < 4) y = read(), change2(x, y);
else printf("%d\n", ask2(x));
}
return 0;
}
V.动态规划
1.动态dp
点击查看代码
const int N = 1e5 + 10;
int n, m, cnt, tot, a[N], fa[N], rk[N], sz[N], dep[N], dfn[N], ed[N], son[N], top[N], head[N], f[N][2];
struct xcj{
int to, nxt;
} e[N << 1];
struct xh{
int mat[2][2];
xh(){memset(mat, 0xcf, sizeof(mat));}
xh operator*(xh x){
xh res;
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int k = 0; k < 2; ++k) res.mat[i][j] = max(res.mat[i][j], mat[i][k] + x.mat[k][j]);
return res;
}
} ans, val[N];
struct xcx{
int l, r;
xh mul;
#define lp p << 1
#define rp p << 1 | 1
#define l(p) t[p].l
#define r(p) t[p].r
#define mul(p) t[p].mul
} t[N << 2];
inline int read(){
int s = 0, w = 1;
char ch = getchar();
for (; ch < '0' || ch > '9'; w *= ch == '-' ? -1 : 1, ch = getchar());
for (; ch >= '0' && ch <= '9'; s = s * 10 + ch - '0', ch = getchar());
return s * w;
}
void add(int u, int v){e[++cnt] = {v, head[u]}, head[u] = cnt;}
void build(int p, int l, int r){
l(p) = l, r(p) = r;
if (l == r){
mul(p) = val[rk[l]];
return ;
}
int mid = (l + r) >> 1;
build(lp, l, mid), build(rp, mid + 1, r), mul(p) = mul(lp) * mul(rp);
}
void change(int p, int x){
if (l(p) == r(p)){
mul(p) = val[rk[x]];
return ;
}
int mid = (l(p) + r(p)) >> 1;
change(x <= mid ? lp : rp, x), mul(p) = mul(lp) * mul(rp);
}
xh ask(int p, int l, int r){
if (l(p) == l && r(p) == r) return mul(p);
int mid = (l(p) + r(p)) >> 1;
if (r <= mid) return ask(lp, l, r);
else if (l > mid) return ask(rp, l, r);
else return ask(lp, l, mid) * ask(rp, mid + 1, r);
}
void dfs1(int x){
sz[x] = 1, son[x] = -1;
for (int i = head[x]; i; i = e[i].nxt){
int y = e[i].to;
if (dep[y]) continue;
dep[y] = dep[x] + 1, fa[y] = x, dfs1(y), sz[x] += sz[y];
if (!~son[x] || sz[y] > sz[son[x]]) son[x] = y;
}
}
void dfs2(int x, int top_x){
top[x] = top_x, rk[dfn[x] = ++tot] = x, ed[top_x] = max(ed[top_x], tot), val[x].mat[0][0] = val[x].mat[0][1] = 0, val[x].mat[1][0] = f[x][1] = a[x];
if (!~son[x]) return ;
dfs2(son[x], top_x), f[x][0] += max(f[son[x]][0], f[son[x]][1]), f[x][1] += f[son[x]][0];
for (int i = head[x]; i; i = e[i].nxt){
int y = e[i].to;
if (y == fa[x] || y == son[x]) continue;
dfs2(y, y), val[x].mat[0][0] = (val[x].mat[0][1] += max(f[y][0], f[y][1])), f[x][0] += max(f[y][0], f[y][1]), val[x].mat[1][0] += f[y][0], f[x][1] += f[y][0];
}
}
void change1(int x, int z){
val[x].mat[1][0] += z - a[x], a[x] = z;
for (xh val1, val2; x; ) val1 = ask(1, dfn[top[x]], ed[top[x]]), change(1, dfn[x]), val2 = ask(1, dfn[top[x]], ed[top[x]]), x = fa[top[x]], val[x].mat[0][0] = (val[x].mat[0][1] += max(val2.mat[0][0], val2.mat[1][0]) - max(val1.mat[0][0], val1.mat[1][0])), val[x].mat[1][0] += val2.mat[0][0] - val1.mat[0][0];
}
signed main(){
n = read(), m = read();
for (int i = 1; i <= n; ++i) a[i] = read();
for (int i = 1, u, v; i < n; ++i) u = read(), v = read(), add(u, v), add(v, u);
dep[1] = 1, dfs1(1), dfs2(1, 1), build(1, 1, n);
for (int x, z; m--; ) x = read(), z = read(), change1(x, z), ans = ask(1, 1, ed[1]), printf("%d\n", max(ans.mat[0][0], ans.mat[1][0]));
return 0;
}