![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 const int mo=1000000007; 2 int n; 3 int ksm(int x,int y) 4 { 5 int z=1; 6 while(y) 7 { 8 if(y&1)z=(1ll*x*z)%mo; 9 y>>=1; x=(1ll*x*x)%mo; 10 } 11 return z; 12 } 13 int t[301][601],c[601]; 14 struct matrix 15 { 16 int a[301][601]; 17 void cheng(matrix &b) //矩阵乘法 18 { 19 for(int i=1;i<=n;i++) 20 for(int j=1;j<=n;j++) 21 { 22 t[i][j]=0; 23 for(int k=1;k<=n;k++)t[i][j]=(1ll*a[i][k]*b.a[k][j]+t[i][j])%mo; 24 } 25 for(int i=1;i<=n;i++) 26 for(int j=1;j<=n;j++)a[i][j]=t[i][j]; 27 } 28 void hswap(int i,int j) //矩阵行交换 29 { 30 for(int k=1;k<=2*n;k++){ int t=a[i][k]; a[i][k]=a[j][k]; a[j][k]=t; } 31 } 32 void hadd(int i,int j,int l) //矩阵行之间加减 33 { 34 for(int k=1;k<=2*n;k++)a[j][k]=(1ll*l*a[i][k]+a[j][k])%mo; 35 } 36 void qiuni() //矩阵求逆 37 { 38 int flag=0; 39 for(int i=1;i<=n;i++)a[i][i+n]=1; 40 for(int i=1;i<=n;i++) 41 { 42 int j=i; while((j<=n)and(a[j][i]==0))j++; 43 if(j>n){ flag=1; break; } 44 if(i!=j)hswap(i,j); 45 for(int j=i+1;j<=n;j++)if(a[j][i]!=0) 46 { 47 int xx=(1ll*a[j][i]*ksm(a[i][i],mo-2))%mo; 48 hadd(i,j,(-xx)%mo); 49 } 50 } 51 if(flag==1){ for(int i=1;i<=n;i++)for(int j=1;j<=2*n;j++)a[i][j]=0; return; } 52 for(int i=n;i>=1;i--) 53 { 54 int xx=ksm(a[i][i],mo-2); hadd(i,i,(xx-1)%mo); 55 for(int j=1;j<i;j++)if(a[j][i]!=0)hadd(i,j,(-a[j][i])%mo); 56 } 57 for(int i=1;i<=n;i++) 58 for(int j=1;j<=n;j++){ a[i][j]=a[i][j+n]; a[i][j+n]=0; } 59 } 60 int det() //求矩阵行列式 61 { 62 int ans=1; 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=n;j++)t[i][j]=a[i][j]; 65 for(int i=1;i<=n;i++) 66 { 67 int j=i; while((j<=n)and(a[j][i]==0))j++; 68 if(j>n)break; 69 if(i!=j)hswap(i,j),ans=-ans; 70 for(int j=i+1;j<=n;j++)if(a[j][i]!=0) 71 { 72 int xx=(1ll*a[j][i]*ksm(a[i][i],mo-2))%mo; 73 hadd(i,j,(-xx)%mo); 74 } 75 } 76 for(int i=1;i<=n;i++)ans=(1ll*ans*a[i][i])%mo; 77 for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]=t[i][j]; 78 return ans; 79 } 80 void zhuanzhi() //矩阵转置 81 { 82 for(int i=1;i<=n;i++) 83 for(int j=1;j<i;j++){ int t=a[i][j]; a[i][j]=a[j][i]; a[j][i]=t; } 84 } 85 void newton() //通过牛顿恒等式求转移矩阵的特征多项式 86 { 87 matrix y; 88 int b[601]; 89 for(int i=1;i<=n;i++) 90 for(int j=1;j<=n;j++)y.a[i][j]=a[i][j]; 91 c[0]=1; 92 for(int i=1;i<=n;i++) 93 { 94 b[i]=0; for(int j=1;j<=n;j++)b[i]=(b[i]+a[j][j])%mo; 95 int tot=0; for(int j=1;j<=i;j++)tot=(tot-1ll*b[j]*c[i-j])%mo; 96 c[i]=(1ll*tot*ksm(i,mo-2))%mo; cheng(y); 97 } 98 for(int i=1;i<=n;i++) 99 for(int j=1;j<=n;j++)a[i][j]=y.a[i][j]; 100 for(int i=0;i<=n/2;i++){ int tt=c[i]; c[i]=c[n-i]; c[n-i]=tt; } 101 } 102 };