矩阵求逆 模板

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/85694296

题目

https://www.luogu.org/problemnew/show/P4783

代码

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int p=1e9+7;
int n;
//定义矩阵及其初等变换 
struct matrix
{
    int a[400][400];

    //矩阵第x行和第y行交换
    void change1(int x, int y)
    {
        for (int i = 0; i < n; ++i)
            swap(a[x][i], a[y][i]);
    }

    //矩阵第x行乘以k
    void change2(int x, int k)
    {
        for (int i = 0; i < n; ++i)
            (((a[x][i] *= k) %= p) += p) %= p;
    }

    //矩阵第x行加上第y行乘以k
    void change3(int x, int y, int k)
    {
        for (int i = 0; i < n; ++i)
            (((a[x][i] += a[y][i] * k % p) %= p) += p) %= p;
    }

    void print()
    {
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                printf("%lld%c", a[i][j], j == n - 1 ? '\n' : ' ');
    }
}a, b; 

int ksm(int x, int y = (p - 2))
{
    int ans = 1;
    while (y > 0)
    {
        if (y & 1)
            (ans *= x) %= p;
        (x *= x) %= p;
        y >>= 1;
    }
    return ans;
}

signed main()
{
    //输入
    scanf("%lld", &n);
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            scanf("%lld", &a.a[i][j]);

    //把B赋值为单位矩阵 
    for (int i = 0; i < n; ++i)
        b.a[i][i] = 1;

    //把A消为上三角矩阵
    for (int i = 0; i < n; ++i)
    {
        if (!a.a[i][i])
            for (int j = i; j < n; ++j)
                if (a.a[j][i])
                {
                    b.change1(i, j);
                    a.change1(i, j);
                    break;
                }
        if (!a.a[i][i])//矩阵不是满秩的
        {
            puts("No Solution");
            return 0;
        }
        b.change2(i, ksm(a.a[i][i]));
        a.change2(i, ksm(a.a[i][i]));
        for (int j = i + 1; j < n; ++j)
        {
            b.change3(j, i, -a.a[j][i]);
            a.change3(j, i, -a.a[j][i]);
        }
    }

    //把A消为单位矩阵 
    for (int i = n - 2; i >= 0; --i)
        for (int j = i +1; j < n; ++j)
        {
            b.change3(i, j, -a.a[i][j]);
            a.change3(i, j, -a.a[i][j]);
        }

    b.print();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/85694296
今日推荐