矩阵模板

  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 };
View Code
posted @ 2017-06-20 20:51  GhoStreach  阅读(218)  评论(0编辑  收藏  举报