c++倍增(快速幂)(矩阵快速幂)(LCA)(ST表求RMQ)

快速幂

举个例子:
2 ^ 10 = 2 ^ 5 * 2 ^ 5 = (2 ^ 2 * 2 ^ 2 * 2) * (2 ^ 2 * 2 ^ 2 * 2) = …
代码奉上

#include
#define LL long long
#define PP pair<int, int>

using namespace std;
LL a, b, mod, ans = 1;
int main () {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> a >> b >> mod;
	if (a == 0) {
		cout << 0 << endl;
		return 0;
	}
	cout << a << '^' << b << " mod " << mod << '=';
	while (b) {
		if (b % 2 == 1) ans = ans * a % mod;
		a = a * a % mod;
		b /= 2;
	}
	cout << ans << endl;
	return 0;
}

矩阵快速幂

矩阵快速幂公式:
c++倍增(快速幂)(矩阵快速幂)(LCA)(ST表求RMQ)_第1张图片
代码奉上

#include
#define LL long long
#define PP pair<int, int>

using namespace std;
const LL N = 1e2 + 10;
const LL mod = 1e9 + 7;
LL a[N][N];
LL ans[N][N];
LL b[N][N];
LL n, k;
void work (LL u[N][N], LL v[N][N]) {
	memset (b, 0, sizeof (b));
	for (LL i = 1; i <= n; i++)
		for (LL j = 1; j <= n; j++)
			for (LL k = 1; k <= n; k++)
				b[i][j] = (b[i][j] + (u[i][k] * v[k][j]) % mod) % mod;
	for (LL i = 1; i <= n; i++)
		for (LL j = 1; j <= n; j++)
			u[i][j] = b[i][j]; 
}
int main () {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> k;
	for (LL i = 1; i <= n; i++)
		for (LL j = 1; j <= n; j++) {
			cin >> a[i][j];
			if (i == j) ans[i][j] = 1;
		}
	while (k) {
		if (k % 2 == 1) work (ans, a);
		work (a, a);
		k /= 2;
	}
	for (LL i = 1; i <= n; i++) {
		for (LL j = 1; j <= n; j++)
			cout << ans[i][j] << ' ';
		cout << endl;
	}
	return 0;
}

矩阵快速幂例题:luoguP1962斐波那契数列

ST表

模版:

#include
#define LL long long
#define PP pair<int, int>

using namespace std;
const int N = 1e5 + 10;
int st[N][25];
int n, m;
int main () {
	scanf ("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf ("%d", &st[i][0]);
	}
	for (int j = 1; j <= 22; 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 len = r - l + 1;
		int k = log (len) / log (2);
		printf ("%d\n", max (st[l][k], st[r - (1 << k) + 1][k]));
	}
	return 0;
}

例题:P2880 [USACO07JAN] Balanced Lineup G

#include
#define LL long long
#define PP pair<int, int>

using namespace std;
const int N = 5e5 + 10;
struct sb {
	int next;
	int to;
};
sb edge[N * 2];
int head[N], cnt;
int n, m, k;
int d[N];//节点深度
int f[N][22];//父亲 
void add (int x, int y) {
	edge[ ++ cnt].next = head[x];
	edge[cnt].to = y;
	head[x] = cnt;
}
void dfs (int x, int fa) {
	for (int i = 1; i <= 19; i ++ ) f[x][i] = f[f[x][i - 1]][i - 1];
	for (int i = head[x]; i; i = edge[i].next) {
		int y = edge[i].to;
		if (y == f[x][0]) continue;
		d[y] = d[x] + 1;
		f[y][0] = x;
		dfs (y, x);
	}		
}
int lca (int x, int y) {
	if (d[x] < d[y]) swap (x, y);
	for (int i = 19; i >= 0; i -- )
		if (d[f[x][i]] >= d[y]) x = f[x][i];
	if (x == y) return x;
	for (int i = 19; i >= 0; i -- )
		if (f[x][i] != f[y][i])
			x = f[x][i], y = f[y][i];
	return f[x][0];
}
int main ()
{
	scanf ("%d%d%d", &n, &m, &k);
	for (int i = 1; i < n; i ++ ) {
		int x, y;
		scanf ("%d%d", &x, &y);
		add (x, y);
		add (y, x);
	}
	d[k] = 1;
	dfs (k, 0);
	while (m -- ) {
		int x, y;
		scanf ("%d%d", &x, &y);
		printf ("%d\n", lca (x, y));
	}
	return 0;
}

例题:P3379 LCA模版

你可能感兴趣的:(基础算法,c++,排序算法,算法)