矩阵快速幂

矩阵快速幂求自幂题目

例:给定A,k,M,求对于指数为 i = (1, ....., k - 1)的A的幂次和对M取模

#include<bits/stdc++.h>

#define int long long
using namespace std;

const int N = 3;

int A, k, M;

void mul(int c[], int a[], int b[][N])
{
	int t[N] = {0};
	for ( int i = 0; i < N; i ++ ) {
		for ( int j = 0; j < N; j ++ ) {
			t[i] = (t[i] + a[j] * b[j][i] % M) % M;
		}
	}
	memcpy(c, t, sizeof t);
}

void mul(int c[][N], int a[][N], int b[][N])
{
	int t[N][N] = {0};
	for ( int i = 0; i < N; i ++ ) {
		for ( int j = 0; j < N; j ++ ) {
			for ( int k = 0; k < N; k ++ ) {
				t[i][j] = (t[i][j] + a[i][k] * a[k][j] % M) % M;
			}
		}
	}
	memcpy(c, t, sizeof t);
}

signed main()
{
	cin >> A >> k >> M;
	int f1[N] = {1, A, 1};
	int b[N][N] = {
		{0, 0, 0},
		{1, A, 1},
		{0, 0, 1}
	};
	k --;
	while (k)
	{
		if (k & 1) mul(f1, f1, b);
		mul(b, b, b);
		k >>= 1;
	}
	cout << f1[2] % M << endl;
	return 0;
}

矩阵快速幂求斐波那契数O(logn)

struct Node{
    int x[2][2];
    Node() {
        x[0][0] = x[0][1] = x[1][0] = 1;
        x[1][1] = 0;
    }
};
 
Node operator *(Node a, Node b)
{
    Node t;
    memset(t.x, 0, sizeof t.x);
    for ( int i = 0; i < 2; i ++ ) {
        for ( int j = 0; j < 2; j ++ ) {
            for ( int k = 0; k < 2; k ++ ) {
                t.x[i][j] = (t.x[i][j] + a.x[i][k] * b.x[k][j]) % mod;
            }
        }
    }
    return t;
}
 
void solve()
{
    int n;
    cin >> n;
    n --;
    Node res, m;
    while (n)
    {
        if (n & 1) res = m * res;
        n >>= 1;
        m = m * m;
    }
    cout << res.x[0][0] << endl;
}

倍增法求斐波那契数(常数比矩阵小)

#define int long long
const int mod = 1e9 + 7;

pair<int, int> fib(int n) {
    if (n == 0) return {0, 1};
    auto p = fib(n >> 1);
    int c = p.first * (2 * p.second - p.first);
    int d = p.first * p.first + p.second * p.second;
    if (n & 1)
        return {(d % mod + mod) % mod, ((c + d) % mod + mod) % mod};
    else
        return {(c % mod + mod) % mod, (d % mod + mod) % mod};
}
//fib(n)函数的返回值记为x,x.second值为第n个斐波那契数
posted @ 2023-03-16 10:09  NUC_ACM开完刀  阅读(16)  评论(0编辑  收藏  举报