zoukankan      html  css  js  c++  java
  • 代数余子式矩阵求行列式

    因为在删除一条边时矩阵只有一行上的两个值发生变化,将上述法则代入该行即可。

    #include <cstdio>
    #include <cmath>
    #define LL long long 
    using namespace std;
    
      int n,m;
      LL sid[100001][3];
      LL tot;
      const LL mo=1e9+7;
      
      LL qpow(LL bas,int powe){
          LL ret=1;
          for (;powe;bas*=bas,bas%=mo){
            if (powe&1) ret*=bas,ret%=mo;
          powe=powe>>1;    
        }
        return(ret);
      }
        
      struct matrix{
          LL a[601][601],tmp[601][601];
          int n,m;
          
          void cpy(matrix&b){
            n=b.n;m=b.m;
          for (int i=1;i<=n;i++)    
            for (int j=1;j<=m;j++)
              a[i][j]=b.a[i][j];
        }
          
          void mul(matrix &b){
          for (int i=0;i<=n;i++) 
            for (int j=0;j<=b.m;j++) 
              tmp[i][j]=0;
            
          for (int i=0;i<=n;i++)
            for (int k=0;k<=m;k++)
              if (a[i][k]) 
                for (int j=0;j<=b.m;j++)
                  tmp[i][j]+=a[i][k]*b.a[k][j]%mo,tmp[i][j]%=mo;
            
          for (int i=0;i<=n;i++)
            for (int j=0;j<=b.m;j++)
              a[i][j]=tmp[i][j];
          m=b.m;
        }
        
        LL det(){
          for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) tmp[i][j]=a[i][j];
          for (int i=1;i<=n;i++){
            for (int j=i+1;j<=n;j++){
              LL bas=a[j][i]*qpow(a[i][i],mo-2)%mo;
              for (int k=i;k<=n;k++)
                a[j][k]-=a[i][k]*bas%mo,a[j][k]%=mo,a[j][k]+=mo,a[j][k]%=mo;
              }    
          }
          LL ret=1;
          for (int i=1;i<=n;i++) ret*=a[i][i],ret%=mo;
          for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) a[i][j]=tmp[i][j];
          return(ret);
        }
        
        void mul(LL num){
          for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
              a[i][j]*=num,a[i][j]%=mo;
        }
        
        void getinv(){
          for (int i=1;i<=n;i++) a[i][n+i]=1;
          for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=(a[i][j]%mo+mo)%mo;
          for (int i=1;i<=n;i++){
            int po;LL maxi=0;
            for (int j=i;j<=n;j++){
              if (fabs(a[j][i])>maxi){
                maxi=fabs(a[j][i]);po=j;
              }
            }
            for (int j=1;j<=2*n;j++){
              LL t=a[i][j];a[i][j]=a[po][j];a[po][j]=t;
            }
            if (fabs(maxi)==0) continue;
                
            for (int j=i+1;j<=n;j++){
              LL tim=a[j][i]*qpow(a[i][i],mo-2)%mo;
              for (int k=i;k<=2*n;k++) a[j][k]-=a[i][k]*tim%mo,a[j][k]%=mo;
              }
            }
            
            for (int i=1;i<=n;i++) for (int j=1;j<=2*n;j++) a[i][j]=(a[i][j]%mo+mo)%mo;
            for (int i=n;i>=1;i--){
              for (int j=i+1;j<=n;j++){
                for (int k=n+1;k<=2*n;k++)
                  a[i][k]-=a[i][j]*a[j][k]%mo,a[i][k]%=mo;
                a[i][j]=0;          
              }
              for (int j=n+1;j<=2*n;j++)
                a[i][j]*=qpow(a[i][i],mo-2),a[i][j]%=mo;
              a[i][i]=1;  
            }
            
            for (int i=1;i<=n;i++)
              for (int j=1;j<=n;j++)
                a[i][j]=(a[i][j+n]%mo+mo)%mo;
        }
        
        void trav(){
          for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
              tmp[i][j]=a[j][i];
          for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
              a[i][j]=tmp[i][j];
        }
      }a,A,inv;
    
      int main(){      
          scanf("%d%d",&n,&m);
          a.n=a.m=n-1;
          for (int i=1;i<=m;i++){
            scanf("%lld%lld%lld",&sid[i][0],&sid[i][1],&sid[i][2]);
            a.a[sid[i][0]][sid[i][1]]--;
            a.a[sid[i][0]][sid[i][0]]++;
        }
        A.n=A.m=n-1;
        for (int i=1;i<n;i++) A.a[i][i]=1;
        A.mul(tot=a.det());
        
        inv.cpy(a);
        inv.getinv();
        A.mul(inv);
        A.trav();
        
        LL ans=0;
        for (int i=1;i<=m;i++){
          if (sid[i][0]==n) continue;
          a.a[sid[i][0]][sid[i][1]]++;
            a.a[sid[i][0]][sid[i][0]]--;
          LL ttot=0;
          for (int j=1;j<n;j++)
            ttot+=a.a[sid[i][0]][j]*A.a[sid[i][0]][j]%mo,ttot%=mo;
          ans+=(tot-ttot)*sid[i][2]%mo;ans%=mo; 
          a.a[sid[i][0]][sid[i][1]]--;
            a.a[sid[i][0]][sid[i][0]]++;
        }
        printf("%lld
    ",(ans%mo+mo)%mo);
      }
  • 相关阅读:
    Server 对象
    Response 对象
    bzoj 5252: [2018多省省队联测]林克卡特树
    bzoj 2167: 公交车站
    bzoj 5315: [Jsoi2018]防御网络
    bzoj 5319: [Jsoi2018]军训列队
    bzoj 4161: Shlw loves matrixI
    bzoj 4942: [Noi2017]整数
    bzoj 2648: SJY摆棋子
    kd-tree 小结
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/7054955.html
Copyright © 2011-2022 走看看