【总结】板板们

杂项

Fast IO
void read (int &x) {
	x = 0; char c = getchar(); bool f = c == '-';
	while (!('0' <= c && c <= '9')) c = getchar(), f |= c == '-';
	while ('0' <= c && c <= '9') x = (x<<1)+(x<<3)+(c-'0'), c = getchar();
	x = f ? -x : x;
}
void write (int x) {
	if (x >= 10) write(x / 10);
	putchar(x%10+'0');
}
mint
struct mint {
	int val;
	mint (int x=0) : val(x) {}
	inline mint operator + (const mint& x) { return val+x.val >= mod ? val+x.val-mod : val+x.val; }
	inline mint operator * (const mint& x) { return 1ll*val*x.val%mod; }
	inline mint operator += (const mint& x) { return *this = *this + x; }
	friend ostream& operator << (ostream& out, const mint& x) { return out << x.val; }
};

数学

CRT
inline int exgcd (const int &a, const int &b, int &x, int &y) {
	if (!b) return x = 1, y = 0, a;
	int d = exgcd(b, a % b, y, x);
	return y -= a / b * x, d;
}
inline int inv (const int &a, const int &m) {
	int x, y, d = exgcd(a, m, x, y);
	return (x % m + m) % m;
}
inline int CRT (const int *a, const int *m) {
	int M = 1, res = 0;
	for (int i = 1; i <= n; i++) M *= m[i];
	for (int i = 1; i <= n; i++) {
		int Mi = M / m[i];
		(res += a[i] * Mi * inv(Mi, m[i])) %= M;
	}
	return res < 0 ? res + M : res;
}
矩阵

Link

#include <bits/stdc++.h>
using namespace std;
const int SIZE = 105, mod = 1e9 + 7;
struct mint {
	int val;
	mint (int x = 0) { val = x % mod; }
	mint operator + (mint x) { return (1ll*val + x.val) % mod; }
	mint operator * (mint x) { return (1ll*val * x.val) % mod; }
	mint operator += (mint x) { return *this = *this + x; }
};
struct Array { mint val[SIZE*SIZE]; };
struct Matrix {
	int n, m; mint a[SIZE][SIZE];
	Matrix (int nn, int mm) {
		n = nn, m = mm;
		for (int i = 1; i <= n; i++) a[i][i] = 1;
	}
	Matrix (int nn, int mm, Array aa) {
		n = nn, m = mm; int _ = 0;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				a[i][j] = aa.val[_++];
	}
	Matrix () {
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				a[i][j] = 0;
	}
	Matrix operator * (Matrix x) {
		Matrix res; res.n = n, res.m = x.m;
		for (int i = 1; i <= res.n; i++)
			for (int j = 1; j <= res.m; j++)
				for (int k = 1; k <= m; k++)
					res.a[i][j] += a[i][k] * x.a[k][j];
		return res; 
	}
};
Matrix qpow (Matrix a, int b) {
	Matrix res(a.n, a.m);
	for (; b; b >>= 1, a = a * a)
		if (b & 1) res = res * a;
	return res;
}
signed main () {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int T; cin >> T;
	while (T--) {
		Matrix a(1, 3, {
			1, 1, 1,
		});
		Matrix b(3, 3, {
			0, 0, 1,
			1, 0, 0,
			0, 1, 1,
		});
		int n; cin >> n;
		if (n <= 3) { cout << "1\n"; continue; }
		cout << (a * qpow(b, n-3)).a[1][3].val << '\n';
	}
	return 0;
}

图论

lca

点的距离

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int n, fa[MAXN][31], dep[MAXN], maxstep;
vector<int> G[MAXN];
void init (int u) {
	dep[u] = dep[fa[u][0]] + 1;
	for (int i = 1; i <= maxstep; i++)
		fa[u][i] = fa[fa[u][i-1]][i-1];
	for (int v : G[u]) if (v != fa[u][0])
		fa[v][0] = u, init(v);
}
int lca (int x, int y) {
	if (dep[x] > dep[y]) swap(x, y);
	for (int diff = dep[y] - dep[x], i = 0; diff; diff>>=1, i++)
		if (diff & 1) y = fa[y][i];
	if (x == y) return x;
	for (int i = maxstep; i >= 0 && fa[x][0] != fa[y][0]; i--)
		if (fa[x][i] != fa[y][i])
			x = fa[x][i], y = fa[y][i];
	return fa[x][0];
}
int main () {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n, maxstep = log2(n);
	for (int i = 1, u, v; i < n; i++)
		cin >> u >> v,
		G[u].push_back(v),
		G[v].push_back(u);
	init(1);
	int q; cin >> q;
	while (q--) {
		int u, v; cin >> u >> v;
		int x = lca(u, v);
		cout << dep[u] + dep[v] - dep[x] * 2 << '\n';
	}
	return 0;
}

数据结构

平衡树

非旋 Treap
#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
#define mk(x, y) make_pair(x, y)
const int MAXN = 1e5 + 5;
int _id, rt;
struct node {
	int rd, key, siz, ls, rs;
} d[MAXN];  // 空间最多为插入的 n 次 
int NewNode (int x) {
	return d[++_id] = {rand(), x, 1, 0, 0}, _id;
}
void push_up (int x) { d[x].siz = d[d[x].ls].siz + d[d[x].rs].siz + 1; }
int Merge (int x, int y) {  // 必须保证 x 内所有的 key < y 内所有的 key 
	if (!x || !y) return x | y;
	if (d[x].rd < d[y].rd) {
		d[x].rs = Merge(d[x].rs, y);
		return push_up(x), x;
	} else {
		d[y].ls = Merge(x, d[y].ls);
		return push_up(y), y;
	}
}
pii Split_key (int x, int y) {   // 按 key 拆 
	if (!x) return mk(0, 0);
	pii res;
	if (d[x].key <= y) {
		res = Split_key(d[x].rs, y);
		d[x].rs = res.first;
		res.first = x;
	} else {
		res = Split_key(d[x].ls, y);
		d[x].ls = res.second;
		res.second = x;
	}
	push_up(x);
	return res;
}
pii Split_siz (int x, int y) {  // 按 siz 拆 
	if (!x) return mk(0, 0);
	if (!y) return mk(0, x);
	pii res;
	if (d[d[x].ls].siz >= y) {
		res = Split_siz(d[x].ls, y);
		d[x].ls = res.second;
		res.second = x;
	} else {
		res = Split_siz(d[x].rs, y - d[d[x].ls].siz - 1);
		d[x].rs = res.first;
		res.first = x;
	}
	push_up(x);
	return res;
}
int Insert (int x, int y) {
	pii t = Split_key(x, y);
	return Merge(Merge(t.first, NewNode(y)), t.second);
}
int Erase (int x, int y) {
	pii t1 = Split_key(x, y), t2 = Split_key(t1.first, y-1);
	return Merge(Merge(t2.first, Merge(d[t2.second].ls, d[t2.second].rs)), t1.second);
}
int Query_id (int y) {
	pii t = Split_key(rt, y-1);
	int res = d[t.first].siz + 1;
	rt = Merge(t.first, t.second);
	return res;
}
int Query_kth (int x, int y) {
	pii t1 = Split_siz(x, y), t2 = Split_siz(t1.first, y-1);
	int res = d[t2.second].key;
	x = Merge(Merge(t2.first, t2.second), t1.second);
	return res;
}
int Query_pre (int y) {
	pii t = Split_key(rt, y-1);
	int res = Query_kth(t.first, d[t.first].siz);
	rt = Merge(t.first, t.second);
	return res;
}
int Query_suf (int y) {
	pii t = Split_key(rt, y);
	int res = Query_kth(t.second, 1);
	rt = Merge(t.first, t.second);
	return res;
}
void Insert (int x) { rt = Insert(rt, x); }
void Erase (int x) { rt = Erase(rt, x); }
int Query_kth (int x) { return Query_kth(rt, x); }
int main () {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int T; cin >> T;
	while (T--) {
		int opt, x; cin >> opt >> x;
		if (opt == 1) Insert(x);
		if (opt == 2) Erase(x);
		if (opt == 3) cout << Query_id(x) << '\n';
		if (opt == 4) cout << Query_kth(x) << '\n';
		if (opt == 5) cout << Query_pre(x) << '\n';
		if (opt == 6) cout << Query_suf(x) << '\n';
	}
	return 0;
} 
posted @ 2023-10-16 16:09  CloudWings  阅读(56)  评论(0编辑  收藏  举报