[ZJ][逆元、降、高斯、短] a542. 行列式det(A)@Morris' Blog|PChome Online 人新台
2012-10-01 20:41:12| 人2,662| 回0 | 上一篇 | 下一篇

[ZJ][逆元、降、高斯、短] a542. 行列式det(A)

0 收藏 0 0 站台

 行列式det(A) 

Background

行 列式在中,是一函,其定域n × n的矩A,取值一量,作det(A)或|A|。行列式可以看做是有向面或的概念在一般的里得空中的推。或者,在 n 里得空中,行列式描述的是一性「」所造成的影。是在性代、多式理,是在微分中(比如元分法中),行列式 作基本的工具,都有著重要的用。

行列式概念最早出在解性方程的程中。十七世晚期,孝和布尼茨的著作中已使用行 列式定性方程解的以及形式。十八世始,行列式始作立的概念被研究。十九世以後,行列式理一步得到展和完善。矩概念的 引入使得更多有行列式的性被,行列式在多域都逐出重要的意和作用,出了性自同和向量的行列式的定。

行列式的特性可以被概括一多次交替性形式,本使得行列式在里德空中可以成描述「」的函。

by Wiki

The Problem

定一 N 矩,算出其行列式值。

入明 :

入的每一行包含多。一料一行包含一整 N,1 < N < 11。接下有 N 行,每行上有 N 整

Aij (-100 < Aij < 100) 。

出明 :

det(A) 可能很大,出 mod 100000007 的答案即可。

例入 :

2 3 4 1 2 3 -9 -18 -27 0 -5 -7 6 -1 3

例出 :

2 144

提示 :

出 :

行列式 (管理:morris1028)


先素做法 : 降 O(N!), 有用到高斯, 逆元


#include <stdio.h>
#include <algorithm>
#define M(x,i,j) (x.v[i][j])
#define mod 100000007LL
using namespace std;
struct matrix {
    int row, col;
    int v[10][10];
};
matrix x[11];
long long det(int dep) {
    int row, col, i, j, k;
    row = x[dep].row, col = x[dep].row;
    if(row == 2)
        return M(x[dep],0,0)*M(x[dep],1,1) - M(x[dep],0,1)*M(x[dep],1,0);
    long long val = 0;
    for(i = 1; i < row; i++) {
        for(j = 1; j < row; j++) {
            M(x[dep+1],i-1,j-1) = M(x[dep],i,j);
        }
    }
    x[dep+1].row = row-1, x[dep+1].col = col-1;
    for(i = 0; i < row; i++) {
        if(i) {
            for(j = 1; j < row; j++)
                M(x[dep+1],j-1,i-1) = M(x[dep],j,i-1);
        }
        if(M(x[dep], 0, i)) {
            val += ((i&1) ? -1 : 1)*det(dep+1)*M(x[dep],0,i);
            if(val >= mod || val <= mod)
                val %= mod;
        }
    }
    return val;
}
int main() {
    int n, i, j, k;
    while(scanf("%d", &n) == 1) {
        x[0].row = n, x[0].col = n;
        for(i = 0; i < n; i++) {
            for(j = 0; j < n; j++) {
                scanf("%d", &x[0].v[i][j]);
            }
        }
        printf("%lld\n", (det(0)+mod)%mod);
    }
    return 0;
}

接下才是重, 我先引用人的

liouzhou_101
「我非常的取模的字,因哪怕你的做法有用到取模字是的特性,但是也了其他做法一很的空。

我的做法是的是高斯消去法,但是除法就暴了。但是我模的是,我可以成乘法,因除以一等於乘上於取模的逆元。

因,在取模的件下,可以先把所有矩中的字取模。

剩下的就是求一於一的逆元了,子你曾出,放在zerojudge上了。」

pcsh710742
根小定理, x^(p-1) ≡ 1 (mod p), 所以模是的候,x的模逆元x^(p-2)

Chih-Hsuan Kuo


假有矩
   3 7
   5 11
  高斯消去, 要把 5 削去, 所以第二列要去第一列乘以 5/3, 5/3 是 1/3 乘以第二列的第一元素, 1/3 在乘法算中是 3 的 inverse, 但我在於魔算, 所以 1/3 替成 3 在下 inverse 即可, 假 inverse 是 x, 那第二列就是去第一列 * x * 5 % mod, 因 3 * x % mod 等於 1, 特性跟除法算中的 3 * 1/3 =1 一, 前面的乘法算都要更正成除法算

自 我
「把目消去成上三角矩就行了, 也就是左下角都 0, 其值是角的乘, 然要全消也行, 此外反矩不存在, det(A) 等於 0, 也就是高斯消去做到一半的候, 抓到首 0 就可以束」

以上大神若不意容公布的, 可以要求下架

#include <stdio.h>
#define LL long long
#define mod 100000007LL
LL inverse(LL x, LL p) {
    if(!p)  return 1;
    if(p&1) return x*inverse((x*x)%mod, p>>1)%mod;
    return inverse((x*x)%mod, p>>1);
}
int main() {
    int n, i, j, k;
    while(scanf("%d", &n) == 1) {
        LL mix[15][15] = {}, tmp;
        for(i = 0; i < n; i++) {
            for(j = 0; j < n; j++) {
                scanf("%lld", &mix[i][j]);
                mix[i][j] = (mix[i][j]+mod)%mod;
            }
        }
        int inch = 0;
        for(i = 0; i < n; i++) {
            int ch = -1;
            for(j = i; j < n; j++) {
                if(mix[j][i]) {
                    ch = j; break;
                }
            }
            if(ch == -1 || !mix[ch][i]) {
                puts("0");  break;
            }
            if(i != ch) {
                for(j = i; j < n; j++)
                    tmp = mix[i][j], mix[i][j] = mix[ch][j], mix[ch][j] = tmp;
                inch++;
            }
            LL inv, sub;
            for(j = 0; j < n; j++) {
                if(i == j || mix[j][i] == 0)  continue;
                inv = inverse(mix[i][i], mod-2);
                sub = (mix[j][i]*inv)%mod;
                for(k = 0; k < n; k++) {
                    mix[j][k] = mix[j][k] - sub*mix[i][k]%mod;
                    mix[j][k] = (mix[j][k]+mod)%mod;
                }
            }
        }
        if(i != n)  continue;
        LL ans = 1;
        for(i = 0; i < n; i++) {
            ans *= mix[i][i];
            ans %= mod;
        }
        if(inch&1)  ans *= -1;
        printf("%lld\n", (ans+mod)%mod);
    }
    return 0;
}

接著什短呢 ? 因是我第一次想修成短, 多一函 sol(), 少 tab 的使用,
接著就靠 define 去了

#include <stdio.h>
#define LL long long
#define FOR(i,x,y) for(i=x;i<y;i++)
#define mod 100000007LL
#define SWAP(T,A,B) {T t;t=A,A=B,B=t;}
LL inv(LL x, LL p) {
    if(!p)  return 1;
    if(p&1) return x*inv((x*x)%mod, p/2)%mod;
    return inv((x*x)%mod, p/2);
}
LL mix[15][15], sub, ans;
int n, i, j, k, inch, ch;
LL sol() {
    inch = 0, ans = 1;
    FOR(i,0,n) {
        ch = i;
        FOR(j,i,n)  if(mix[j][i]) {ch = j; break;}
        if(!mi[ch][i]) return 0;
        if(i != ch) {
            FOR(j,i,n)  SWAP(LL,mix[i][j],mix[ch][j]);
            inch++;
        }
        FOR(j,i+1,n) {
            if(!mix[j][i])  continue;
            sub = (mix[j][i]*inv(mix[i][i], mod-2))%mod;
            FOR(k,i,n)
                mix[j][k] = (mix[j][k]-sub*mix[i][k]%mod+mod)%mod;
        }
        ans = (ans*mix[i][i])%mod;
    }
    if(inch&1)  ans *= -1;
    return (ans+mod)%mod;
}
int main() {
    while(scanf("%d", &n) == 1) {
        FOR(i,0,n) {
            FOR(j,0,n) {
                scanf("%lld", &mix[i][j]);
                mix[i][j] = (mix[i][j]+mod)%mod;
            }
        }
        printf("%lld\n", sol());
    }
    return 0;
}

台: Morris
人(2,662) | 回(0)| 推 (0)| 收藏 (0)|
全站分: 不分 | 人分: ZeroJudge |
此分下一篇:[ZJ][LCA][online] d767. 血
此分上一篇:[ZJ][dp] a449. 王的接
是 (若未登入"人新台"看不到回覆唷!)
* 入:
入片中算式的果(可能0) 
(有*必填)
TOP
全文
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86