poj 3233 +Matrix Power Series,矩阵快速幂
题目连接:Matrix Power Series
题意:给一个n*n的矩阵A,求矩阵A+A^1+A^2+......+A^k;
题解:构造一个矩阵为n*2n的(形如AE)名字为BB,和一个2n*2n的矩阵AA如下图
然后答案就是BB*AA^k-1的前面n*n;
#include<cstdio> #define ll long long using namespace std; int mod=1e9+7; const int maxn=1e5+10; int n; struct mat { int n, m; ll a[100][100]; mat() {} void init(int _n, int _m) { n = _n; m = _m; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) a[i][j] = 0; } } void one() { init(2,2);a[0][0]=1;a[1][1]=1; } mat operator + (const mat &B)const { mat C; C.init(n,m); for(int i=0; i<n; i++) for(int j=0; j<m; j++) C.a[i][j]=(a[i][j]+B.a[i][j])%mod; return C; } mat operator*(const mat &P)const { mat ret; ret.init(n,m); for(int i = 0; i < n; i++) { for(int k = 0; k < m; k++) { if(a[i][k]) { for(int j = 0; j < P.m; j++) { ret.a[i][j] = ((ll)a[i][k] * P.a[k][j] + ret.a[i][j]) % mod; } } } } return ret; } mat operator^(const ll &P)const { ll num = P; mat ret, tmp = *this; ret.init(n,m); for(int i = 0; i < n; i++) ret.a[i][i] = 1; while(num) { if(num & 1) ret = ret * tmp; tmp = tmp * tmp; num >>= 1; } return ret; } void view() { for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { printf("%lld ",a[i][j]); }printf("\n"); } } }; int main() { mat a,aa; int n,k; scanf("%d %d %d",&n,&k,&mod); a.init(n,2*n); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { scanf("%d",&a.a[i][j]); } a.a[i][i+n]=1; } aa.init(2*n,2*n); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { aa.a[i+n][j]=aa.a[i][j]=a.a[i][j]; } } for(int i=0;i<n;i++) { aa.a[i+n][i+n]=1; } a=a*(aa^(k-1)); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { printf("%lld ",a.a[i][j]); }printf("\n"); } return 0; }