[笔记]各种模板

启动。

快排(带随机)

void qsort(int l, int r) {
	if (l >= r) return;
	vector<int> p, q; p.clear(), q.clear();
	for (int i = l; i <= r; i ++ ) {
		if (a[i] < a[l]) p.push_back(a[i]);
		if (a[i] > a[l]) q.push_back(a[i]);
	}
	int u = l, v = r, val = a[l]; 
	for (int i : p) a[u ++ ] = i;
	for (int i : q) a[v -- ] = i;
	for (int i = u; i <= v; i ++ ) a[i] = val;
	qsort(l, u - 1); qsort(v + 1, r);
}
int main() {
	random_shuffle(a + 1, a + n + 1);
	qsort(1, n);
}

归并排序

void merge(int l, int r) {
	if (l >= r) return;
	int mid = l + r >> 1;
	merge(l, mid), merge(mid + 1, r);
	int i = l, j = mid + 1; vector<int> tmp;
	while (i <= mid and j <= r) 
		tmp.push_back((a[i] < a[j] ? a[i ++ ] : a[j ++ ]));
	while (i <= mid) tmp.push_back(a[i ++ ]);
	while (j <= r) tmp.push_back(a[j ++ ]);
	for (int i : tmp) a[l ++ ] = i;
}

单调队列(滑窗)

int n, k, a[N], q[N], hh, tt;
int main() {
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i ++ )
		scanf("%d", &a[i]);
	hh = 1, tt = 0;
	for (int i = 1; i <= n; i ++ ) {
		while (hh <= tt and q[hh] <= i - k) hh ++ ;
		while (hh <= tt and a[q[tt]] >= a[i]) tt -- ;
		q[ ++ tt] = i; if (i >= k) printf("%d ", a[q[hh]]);
	} hh = 1, tt = 0; puts("");
	for (int i = 1; i <= n; i ++ ) {
		while (hh <= tt and q[hh] <= i - k) hh ++ ;
		while (hh <= tt and a[q[tt]] <= a[i]) tt -- ;
		q[ ++ tt] = i; if (i >= k) printf("%d ", a[q[hh]]);
	} return 0;
}

三分

const double eps = 1e-6;
int n; double l, r, a[20];
double f(double x) {
	double fac = 1.00, ans = 0.00;
	for (int i = 0; i <= n; i ++ )
		ans += a[i] * fac, fac *= x;
	return ans;
}
double search(double l, double r) {
	if (fabs(r - l) <= eps) return l;
	double mid1 = l + (r - l) / 3.0;
	double mid2 = r - (r - l) / 3.0;
	if (f(mid1) > f(mid2)) return search(l, mid2);
	else return search(mid1, r);
}
int main() {
	scanf("%d%lf%lf", &n, &l, &r);
	for (int i = n; ~i; i -- )
		scanf("%lf", &a[i]);
	printf("%.10lf\n", search(l, r));
}

矩阵快速幂

int Mod(int a, int b) {
	return (a % mod + b % mod + mod) % mod;
}
struct Matrix {
	#define MAX 100
	#define all(i) for (int i = (0); i < MAX; i ++ )
	int a[MAX][MAX];
	Matrix() { memset(a, 0, sizeof a); }
	void makeI() { all(i) a[i][i] = 1; }
	int *operator [] (const int &x) { return a[x]; }
	Matrix operator + (Matrix &b)const {
		Matrix ans; all(i) all(j)
			ans[i][j] = Mod(a[i][j], b[i][j]); return ans;
	}
	Matrix operator - (Matrix &b)const {
		Matrix ans; all(i) all(j) 
			ans[i][j] = Mod(a[i][j], -b[i][j]); return ans;
	}
	Matrix operator * (Matrix &b)const {
		Matrix ans; all(i) all(j) all(k) 
		ans[i][j] = Mod(ans[i][j], a[i][k] * b[k][j] % mod); return ans;
	}
	Matrix operator ^ (int b)const {
		Matrix ans, tmp = *this; ans.makeI();
		for (; b; b >>= 1, tmp = tmp * tmp)
			if (b & 1) ans = ans * tmp; return ans;
	}
}M;

signed main() {
	scanf("%lld%lld", &n, &k);
	for (int i = 0; i < n; i ++ )
		for (int j = 0; j < n; j ++ )
			scanf("%lld", &M[i][j]);
	M = M ^ k;
}

树状数组 1

int n, m, tr[N];

int main() {
	auto add = [&](int x, int v) {
		for (int i = x; i <= n; i += lowbit(i))
			tr[i] += v;
	};
	auto query = [&](int x) -> int {
		int ans = 0;
		for (int i = x; i; i -= lowbit(i))
			ans += tr[i]; return ans;
	};
	scanf("%d%d", &n, &m);
	for (int i = 1, x; i <= n; i ++ )
		scanf("%d", &x), add(i, x);
	while (m -- ) {
		int op, a, b; scanf("%d%d%d", &op, &a, &b);
		if (op & 1) add(a, b);
		else printf("%d\n", query(b) - query(a - 1));
	} return 0;
}

树状数组 2

int n, m, tr[N], w[N];

signed main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++ )
		scanf("%d", &w[i]);
	auto add = [&](int x, int v) {
		for (int i = x; i <= n; i += lowbit(i))
			tr[i] += v;
	};
	auto query = [&](int x) -> int {
		int ans = 0;
		for (int i = x; i; i -= lowbit(i))
			ans += tr[i]; return ans;
	};
	while (m -- ) {
		int op, x, y, k; scanf("%d", &op);
		if (op & 1) scanf("%d%d%d", &x, &y, &k),
			add(x, k), add(y + 1, -k);
		else scanf("%d", &x),
			printf("%d\n", w[x] + query(x));
	}
}

树状数组 3(区间加区间查询)

int n, m, tr1[N], tr2[N], a[N];

signed main() {
	auto add = [&](int *tr, int x, int v) {
		for (int i = x; i <= n; i += lowbit(i))
			tr[i] += v;
	};
	auto query = [&](int *tr, int x) {
		int ans = 0;
		for (int i = x; i; i -= lowbit(i))
			ans += tr[i]; return ans;
	};
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; i ++ ) {
		scanf("%lld", &a[i]);
		add(tr1, i, a[i] - a[i - 1]);
		add(tr2, i, (i - 1) * (a[i] - a[i - 1]));
	}
	while (m -- ) {
		int op, l, r, v;
		scanf("%lld%lld%lld", &op, &l, &r);
		if (op & 1) {
			scanf("%lld", &v);
			add(tr1, l, v);
			add(tr1, r + 1, -v);x
			add(tr2, l, (l - 1) * v);
			add(tr2, r + 1, - r * v);
		} else {
			l -- ;
			printf("%lld\n", query(tr1, r) * r - query(tr2, r) - 
							 query(tr1, l) * l + query(tr2, l));
		}
	} return 0;
}

乘法逆元 1

int fac[N], inv[N], n, p;
int qpow(int a, int b = p - 2) {
	int ans = 1; for (; b; b >>= 1, a = 1ll * a * a % p)
		if (b & 1) ans = 1ll * ans * a % p; return ans;
}
int main() {
	scanf("%d%d", &n, &p); fac[0] = 1;
	for (int i = 1; i <= n; i ++ )
		fac[i] = 1ll * fac[i - 1] * i % p;
	inv[n] = qpow(fac[n]);
	for (int i = n - 1; i >= 1; i -- )
		inv[i] = 1ll * inv[i + 1] * (i + 1) % p;
	for (int i = 1; i <= n; i ++ )
		inv[i] = 1ll * inv[i] * fac[i - 1] % p;
	for (int i = 1; i <= n; i ++ )
		printf("%d\n", inv[i]);
}

乘法逆元 2

int n, p, k, ans, a[N], fac[N], inv[N];

int qpow(int a, int b = p - 2) {
	int ans = 1; for (; b; b >>= 1, a = 1ll * a * a % p)
		if (b & 1) ans = 1ll * ans * a % p; return ans;
}
int main() {
	read(n, p, k); fac[0] = 1;
	for (int i = 1; i <= n; i ++ ) {
		read(a[i]);
		fac[i] = 1ll * fac[i - 1] * a[i] % p;
	}
	inv[n] = qpow(fac[n]);
	for (int i = n - 1; i; i -- )
		inv[i] = 1ll * inv[i + 1] * a[i + 1] % p;
	for (int i = 1; i <= n; i ++ ) {
		inv[i] = 1ll * inv[i] * fac[i - 1] % p;
		ans = (ans + 1ll * (fac[0] = 1ll * fac[0] * k % p) * inv[i] % p) % p;
	}
}

dijkstra

priority_queue<PII, vector<PII>, greater<PII>> q;
fill(dist, dist + n + 1, (1ll << 31) - 1);
dist[s] = 0; q.push({0, s});
while (q.size()) {
	int u = q.top().second; q.pop();
	if (st[u]) continue; st[u] = true;
	for (int i = h[u]; i; i = ne[i]) {
		int v = e[i];
		if (dist[v] > dist[u] + w[i]) {
			dist[v] = dist[u] + w[i];
			if (!st[v]) q.push({dist[v], v});
		}
	}
}
for (int i = 1; i <= n; i ++ )
	printf("%d ", dist[i]);

SPFA

fill(dist, dist + n + 1, (1ll << 31) - 1);
queue<int> q; q.push(s); dist[s] = 0; st[s] = true;
while (q.size()) {
	int u = q.front(); q.pop();
	st[u] = false; for (int i = h[u]; i; i = ne[i]) {
		int v = e[i]; if (dist[v] > dist[u] + w[i]) {
			dist[v] = dist[u] + w[i]; 
			if (!st[v]) st[v] = true, q.push(v);
		}
	}
}

KMP

scanf("%s%s", s1 + 1, s2 + 1);
n = strlen(s1 + 1), m = strlen(s2 + 1);
for (int i = 2, j = 0; i <= m; i ++ ) {
	while (j and s2[i] != s2[j + 1]) j = ne[j];
	ne[i] = (s2[i] == s2[j + 1]) ? ( ++ j) : j;
}
for (int i = 1, j = 0; i <= n; i ++ ) {
	while (j and s2[j + 1] != s1[i]) j = ne[j];
	if ((s2[j + 1] == s1[i] ? ++ j : j) == m) 
		printf("%d\n", i - m + 1);
}

ST 表

for (int i = 2; i <= n; i ++ )
	lg[i] = lg[i >> 1] + 1;
for (int i = 1; i <= n; i ++ )
	scanf("%d", &st[i][0]);
for (int j = 1; j <= lg[n]; j ++ )
	for (int i = 1; i + (1 << j - 1) <= n; i ++ )
		st[i][j] = max(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
while (m -- ) {
	int l, r; scanf("%d%d", &l, &r);
	int d = lg[r - l + 1];
	printf("%d\n", max(st[l][d], st[r - (1 << d) + 1][d]));
}

Bezout 定理

int gcd(int a, int b) {
	return !b ? a : gcd(b, a % b);
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i ++ )
		scanf("%d", &a[i]);
	for (int i = 1; i <= n; i ++ )
		d = gcd(a[i] < 0 ? - a[i] : a[i], d);
	printf("%d\n", d); return 0;
}

单调栈

for (int i = n; i; i -- ) {
	while (top and a[stk[top]] <= a[i]) top -- ;
	ne[i] = stk[top]; stk[ ++ top] = i;
} 

康托展开

auto add = [&](int x, int v) {
	for (int i = x; i <= n; i += lowbit(i))
		tr[i] += v;
};
auto query = [&](int x) {
	int s = 0; for (int i = x; i; i -= lowbit(i))
		s += tr[i]; return s;
};
for (int i = 1; i <= n; i ++ )
	add(i, 1); fac[0] = 1ll;
for (int i = 1; i <= n; i ++ )
	fac[i] = 1ll * fac[i - 1] * i % mod;
for (int i = 1; i <= n; i ++ ) {
	int qwq = query(a[i] - 1); add(a[i], -1);
	ans = 1ll * (ans + 1ll * qwq * fac[n - i]) % mod;
} printf("%d\n", (ans + 1) % mod);

最长公共子序列

我比较傻,不会二分,只会线段树优化

void build(int u, int l, int r) {
	tr[u] = {l, r};
	if (l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void modify(int u, int x, int v) {
	tr[u].mx = max(tr[u].mx, v);
	if (tr[u].l == tr[u].r) return;
	if (x <= mid) modify(ls, x, v);
	else modify(rs, x, v);
}
int query(int u, int l, int r) {
	if (tr[u].l >= l and tr[u].r <= r)
		return tr[u].mx;
	int s = 0; if (l <= mid) s = query(ls, l, r);
	if (r > mid) s = max(s, query(rs, l, r)); return s;
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i ++ )
		scanf("%d", &s[i]);
	for (int i = 1; i <= n; i ++ )
		scanf("%d", &t[i]);
	for (int i = 1; i <= n; i ++ )
		id[s[i]] = i;
	for (int i = 1; i <= n; i ++ )
		t[i] = id[t[i]];
	build(1, 1, n);
	for (int i = 1; i <= n; i ++ ) {
		f[i] = query(1, 1, t[i]) + 1;
		modify(1, t[i], f[i]);
	}
	int ans = 0;
	for (int i = 1; i <= n; i ++ )
		ans = max(ans, f[i]);
	printf("%d\n", ans); 
	return 0;
}

拉格朗日插值

int n, k, ans, x[N], y[N];
int Mod(int x, int y) {
	return (x + y + mod) % mod;
}
int qpow(int a, int b = mod - 2) {
	int ans = 1; for (; b; b >>= 1, a = a * a % mod)
		if (b & 1) ans = ans * a % mod; return ans;
}
signed main() {
	scanf("%lld%lld", &n, &k);
	for (int i = 1; i <= n; i ++ )
		scanf("%lld%lld", &x[i], &y[i]);
	for (int i = 1; i <= n; i ++ ) {
		int now = 1; for (int j = 1; j <= n; j ++ ) {
			if (j != i) now = now * Mod(k, -x[j]) % mod * qpow(Mod(x[i], -x[j])) % mod;
		} ans = Mod(ans, y[i] * now);
	} printf("%lld\n", ans); return 0;
}

笛卡尔树

for (int i = 1; i <= n; i ++ ) {
	while (top and w[stk[top]] > w[i]) top -- ;
	if (!top) ls[i] = stk[top + 1];
	else ls[i] = rs[stk[top]], rs[stk[top]] = i;
	stk[ ++ top] = i; 
}

有理数取余

void read(int &x) {
	x = 0; char ch = getchar();
	for (; ch < '0' or ch > '9'; ch = getchar());
	for (; ch >= '0' and ch <= '9'; ch = getchar())
		x = ((x << 1) + (x << 3) + (ch ^ 48)) % mod;
}
int qpow(int a, int b = mod - 2) {
	int ans = 1;
	for (; b; b >>= 1, a = a * a % mod)
		if (b & 1) ans = ans * a % mod; return ans;
}
signed main() {
	read(a), read(b);
	printf("%lld\n", a * qpow(b) % mod);
}
posted @ 2024-11-28 21:19  Link-Cut-Y  阅读(1)  评论(0编辑  收藏  举报