• 矩阵快速幂


    poj 3070 Fibonacci http://poj.org/problem?id=3070

    模板题,矩阵都给你写好了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define mt(a,b) memset(a,b,sizeof(a))
     4 class Matrix { ///矩阵
     5     typedef int typev;///权值类型
     6     static const int MV=2;///矩阵长度
     7     static const int mod=10000;///%mod
     8     friend Matrix operator *(const Matrix &a,const Matrix &b) { ///矩阵乘法,必须a的列等于b的行
     9         Matrix ret;
    10         ret.n=a.n;
    11         ret.m=b.m;
    12         ret.zero();
    13         if(a.m==b.n) {
    14             for(int k=0; k<a.m; k++) {
    15                 for(int i=0; i<a.n; i++) {
    16                     if(a.val[i][k]) {
    17                         for(int j=0; j<b.m; j++) {
    18                             ret.val[i][j]+=a.val[i][k]*b.val[k][j];
    19                             ret.val[i][j]%=mod;///看具体需要
    20                         }
    21                     }
    22                 }
    23             }
    24         }
    25         return ret;
    26     }
    27     friend Matrix operator ^ (Matrix &a,int b) {///必须是n*n方阵才能快速幂
    28         Matrix ret;
    29         ret.n=ret.m=a.n;
    30         ret.unit();
    31         for(; b; a=a*a,b>>=1) {
    32             if(b&1) {
    33                 ret=ret*a;
    34             }
    35         }
    36         return ret;
    37     }
    38 public:
    39     int n,m;///n行m列
    40     typev val[MV][MV];
    41     void zero() {
    42         mt(val,0);
    43     }
    44     void unit() {
    45         zero();
    46         for(int i=0; i<MV; i++)
    47             val[i][i]=1;
    48     }
    49 } A;
    50 int main() {
    51     int n;
    52     while(~scanf("%d",&n),n>-1) {
    53         A.n=A.m=2;
    54         A.val[0][0]=1;
    55         A.val[0][1]=1;
    56         A.val[1][0]=1;
    57         A.val[1][1]=0;
    58         printf("%d
    ",(A^n).val[0][1]);
    59     }
    60     return 0;
    61 }
    View Code

     hdu 1575  Tr A  http://acm.hdu.edu.cn/showproblem.php?pid=1575

    模板题

     1 #include<cstdio>
     2 #include<cstring>
     3 #define mt(a,b) memset(a,b,sizeof(a))
     4 const int MOD=9973;
     5 class Matrix { ///矩阵 下标0开始
     6     typedef int typev;///权值类型
     7     static const int MV=16;///矩阵长度
     8     static const int mod=MOD;///%mod
     9     friend Matrix operator *(const Matrix &a,const Matrix &b) { ///矩阵乘法,必须a的列等于b的行
    10         Matrix ret;
    11         ret.n=a.n;
    12         ret.m=b.m;
    13         ret.zero();
    14         if(a.m==b.n) {
    15             for(int k=0; k<a.m; k++) {
    16                 for(int i=0; i<a.n; i++) {
    17                     if(a.val[i][k]) {
    18                         for(int j=0; j<b.m; j++) {
    19                             ret.val[i][j]+=a.val[i][k]*b.val[k][j];
    20                             ret.val[i][j]%=mod;///看具体需要
    21                         }
    22                     }
    23                 }
    24             }
    25         }
    26         return ret;
    27     }
    28     friend Matrix operator ^ (Matrix &a,int b) {///必须是n*n方阵才能快速幂
    29         Matrix ret;
    30         ret.n=ret.m=a.n;
    31         ret.unit();
    32         for(; b; a=a*a,b>>=1) {
    33             if(b&1) {
    34                 ret=ret*a;
    35             }
    36         }
    37         return ret;
    38     }
    39 public:
    40     int n,m;///n行m列
    41     typev val[MV][MV];
    42     void zero() {
    43         mt(val,0);
    44     }
    45     void unit() {
    46         zero();
    47         for(int i=0; i<MV; i++)
    48             val[i][i]=1;
    49     }
    50 } A;
    51 int main() {
    52     int t,n,k;
    53     while(~scanf("%d",&t)){
    54         while(t--){
    55             scanf("%d%d",&n,&k);
    56             A.n=A.m=n;
    57             for(int i=0;i<n;i++){
    58                 for(int j=0;j<n;j++){
    59                     scanf("%d",&A.val[i][j]);
    60                 }
    61             }
    62             A=A^k;
    63             int ans=0;
    64             for(int i=0;i<n;i++){
    65                 ans+=A.val[i][i];
    66                 ans%=MOD;
    67             }
    68             printf("%d
    ",ans);
    69         }
    70     }
    71     return 0;
    72 }
    View Code

    Kiki & Little Kiki 2 http://acm.hdu.edu.cn/showproblem.php?pid=2276

    矩阵先不说了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define mt(a,b) memset(a,b,sizeof(a))
     4 class Matrix { ///矩阵 下标0开始
     5     typedef int typev;///权值类型
     6     static const int MV=128;///矩阵长度
     7     static const int mod=2;///%mod
     8     friend Matrix operator *(const Matrix &a,const Matrix &b) { ///矩阵乘法,必须a的列等于b的行
     9         Matrix ret;
    10         ret.n=a.n;
    11         ret.m=b.m;
    12         ret.zero();
    13         if(a.m==b.n) {
    14             for(int k=0; k<a.m; k++) {
    15                 for(int i=0; i<a.n; i++) {
    16                     if(a.val[i][k]) {
    17                         for(int j=0; j<b.m; j++) {
    18                             ret.val[i][j]+=a.val[i][k]*b.val[k][j];
    19                             ret.val[i][j]%=mod;///看具体需要
    20                         }
    21                     }
    22                 }
    23             }
    24         }
    25         return ret;
    26     }
    27     friend Matrix operator ^ (Matrix &a,int b) {///必须是n*n方阵才能快速幂
    28         Matrix ret;
    29         ret.n=ret.m=a.n;
    30         ret.unit();
    31         for(; b; a=a*a,b>>=1) {
    32             if(b&1) {
    33                 ret=ret*a;
    34             }
    35         }
    36         return ret;
    37     }
    38 public:
    39     int n,m;///n行m列
    40     typev val[MV][MV];
    41     void zero() {
    42         mt(val,0);
    43     }
    44     void unit() {
    45         zero();
    46         for(int i=0; i<MV; i++)
    47             val[i][i]=1;
    48     }
    49 } A,T;
    50 int main(){
    51     int n;
    52     char s[128];
    53     while(~scanf("%d%s",&n,s)){
    54         int ls=strlen(s);
    55         A.n=A.m=T.n=T.m=ls;
    56         A.zero();
    57         T.unit();
    58         for(int i=0;i<ls;i++){
    59             if(s[i]=='1'){
    60                 A.val[0][i]=1;
    61             }
    62             T.val[i][i+1]=1;
    63         }
    64         T.val[ls-1][0]=1;
    65         A=A*(T^n);
    66         for(int i=0;i<ls;i++){
    67             printf("%d",A.val[0][i]);
    68         }
    69         puts("");
    70     }
    71     return 0;
    72 }
    View Code

     Matrix Power Series http://poj.org/problem?id=3233

    测模板,具体构造再说吧。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define mt(a,b) memset(a,b,sizeof(a))
     4 int mod;
     5 class Matrix { ///矩阵 下标0开始
     6     typedef int typev;///权值类型
     7     static const int MV=64;///矩阵长度
     8     friend Matrix operator *(const Matrix &a,const Matrix &b) { ///矩阵乘法,必须a的列等于b的行
     9         Matrix ret;
    10         ret.n=a.n;
    11         ret.m=b.m;
    12         ret.zero();
    13         if(a.m==b.n) {
    14             for(int k=0; k<a.m; k++) {
    15                 for(int i=0; i<a.n; i++) {
    16                     if(a.val[i][k]) {
    17                         for(int j=0; j<b.m; j++) {
    18                             ret.val[i][j]+=a.val[i][k]*b.val[k][j];
    19                             ret.val[i][j]%=mod;///看具体需要
    20                         }
    21                     }
    22                 }
    23             }
    24         }
    25         return ret;
    26     }
    27     friend Matrix operator ^ (Matrix &a,int b) {///必须是n*n方阵才能快速幂
    28         Matrix ret;
    29         ret.n=ret.m=a.n;
    30         ret.unit();
    31         for(; b; a=a*a,b>>=1) {
    32             if(b&1) {
    33                 ret=ret*a;
    34             }
    35         }
    36         return ret;
    37     }
    38 public:
    39     int n,m;///n行m列
    40     typev val[MV][MV];
    41     void zero() {
    42         mt(val,0);
    43     }
    44     void unit() {
    45         zero();
    46         for(int i=0; i<MV; i++)
    47             val[i][i]=1;
    48     }
    49 } A;
    50 int main(){
    51     int n,k;
    52     scanf("%d%d%d",&n,&k,&mod);
    53     A.n=A.m=n<<1;
    54     for(int i=0;i<n;i++){
    55         for(int j=0;j<n;j++){
    56             scanf("%d",&A.val[i][j]);
    57             A.val[i][j+n]=A.val[i][j];
    58             A.val[i+n][j]=0;
    59             A.val[i+n][j+n]=0;
    60             if(i+n==j+n)
    61                 A.val[i+n][j+n]=1;
    62         }
    63     }
    64     A=A^k;
    65     for(int i=0;i<n;i++){
    66         for(int j=n;j<A.n;j++)
    67             printf("%d ",A.val[i][j]);
    68         puts("");
    69     }
    70     return 0;
    71 }
    View Code

    Training little cats  http://poj.org/problem?id=3735

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define mt(a,b) memset(a,b,sizeof(a))
     5 using namespace std;
     6 typedef __int64 LL;
     7 class Matrix { ///矩阵 下标0开始
     8     typedef LL typev;///权值类型
     9     static const int MV=128;///矩阵长度
    10     static const int mod=10000;///%mod
    11     friend Matrix operator *(const Matrix &a,const Matrix &b) { ///矩阵乘法,必须a的列等于b的行
    12         Matrix ret;
    13         ret.n=a.n;
    14         ret.m=b.m;
    15         ret.zero();
    16         if(a.m==b.n) {
    17             for(int k=0; k<a.m; k++) {
    18                 for(int i=0; i<a.n; i++) {
    19                     if(a.val[i][k]) {
    20                         for(int j=0; j<b.m; j++) {
    21                             ret.val[i][j]+=a.val[i][k]*b.val[k][j];
    22 //                            ret.val[i][j]%=mod;///看具体需要
    23                         }
    24                     }
    25                 }
    26             }
    27         }
    28         return ret;
    29     }
    30     friend Matrix operator ^ (Matrix &a,int b) {///必须是n*n方阵才能快速幂
    31         Matrix ret;
    32         ret.n=ret.m=a.n;
    33         ret.unit();
    34         for(; b; a=a*a,b>>=1) {
    35             if(b&1) {
    36                 ret=ret*a;
    37             }
    38         }
    39         return ret;
    40     }
    41 public:
    42     int n,m;///n行m列
    43     typev val[MV][MV];
    44     void zero() {
    45         mt(val,0);
    46     }
    47     void unit() {
    48         zero();
    49         for(int i=0; i<MV; i++)
    50             val[i][i]=1;
    51     }
    52 } A;
    53 int main(){
    54     int x,y,n,m,k;
    55     char op[4];
    56     while(~scanf("%d%d%d",&n,&m,&k),n+m+k){
    57         A.unit();
    58         A.n=A.m=n+1;
    59         while(k--){
    60             scanf("%s%d",op,&x);
    61             switch(op[0]){
    62                 case 'g':   A.val[0][x]++;  break;
    63                 case 'e':   for(int i=0;i<=n;i++)   A.val[i][x]=0;  break;
    64                 default:    scanf("%d",&y); for(int i=0;i<=n;i++)   swap(A.val[i][x],A.val[i][y]);
    65             }
    66         }
    67         A=A^m;
    68         for(int i=1;i<=n;i++)   printf("%I64d ",A.val[0][i]);
    69         puts("");
    70     }
    71     return 0;
    72 }
    View Code

    Fast Matrix Calculation http://acm.hdu.edu.cn/showproblem.php?pid=4965

      1 #include<cstdio>
      2 #include<cstring>
      3 #define mt(a,b) memset(a,b,sizeof(a))
      4 typedef __int64 LL;
      5 class Matrix { ///矩阵 下标0开始
      6     typedef int typev;///权值类型
      7     static const int MV=8;///矩阵长度
      8     static const int mod=6;///%mod
      9     friend Matrix operator *(const Matrix &a,const Matrix &b) { ///矩阵乘法,必须a的列等于b的行
     10         Matrix ret;
     11         ret.n=a.n;
     12         ret.m=b.m;
     13         ret.zero();
     14         if(a.m==b.n) {
     15             for(int k=0; k<a.m; k++) {
     16                 for(int i=0; i<a.n; i++) {
     17                     if(a.val[i][k]) {
     18                         for(int j=0; j<b.m; j++) {
     19                             ret.val[i][j]+=a.val[i][k]*b.val[k][j];
     20                             ret.val[i][j]%=mod;///看具体需要
     21                         }
     22                     }
     23                 }
     24             }
     25         }
     26         return ret;
     27     }
     28     friend Matrix operator ^ (Matrix &a,int b) {///必须是n*n方阵才能快速幂
     29         Matrix ret;
     30         ret.n=ret.m=a.n;
     31         ret.unit();
     32         for(; b; a=a*a,b>>=1) {
     33             if(b&1) {
     34                 ret=ret*a;
     35             }
     36         }
     37         return ret;
     38     }
     39 public:
     40     int n,m;///n行m列
     41     typev val[MV][MV];
     42     void zero() {
     43         mt(val,0);
     44     }
     45     void unit() {
     46         zero();
     47         for(int i=0; i<MV; i++)
     48             val[i][i]=1;
     49     }
     50 } D;
     51 struct mat {
     52     int n,m;
     53     int data[1024][1024];
     54 }A,B,C,E;
     55 class MatrixOp {
     56 public:
     57     int mul(mat& c,const mat& a,const mat& b) {  //c=a*b
     58         int i,j,k;
     59         if (a.m!=b.n) return 0;
     60         c.n=a.n,c.m=b.m;
     61         for (i=0; i<c.n; i++)
     62             for (j=0; j<c.m; j++)
     63                 for (c.data[i][j]=k=0; k<a.m; k++)
     64                     c.data[i][j]+=a.data[i][k]*b.data[k][j];
     65         return 1;
     66     }
     67 } gx;
     68 int main(){
     69     int N,K;
     70     while(~scanf("%d%d",&N,&K),N|K){
     71         A.n=N;
     72         A.m=K;
     73         B.n=K;
     74         B.m=N;
     75         for(int i=0;i<N;i++){
     76             for(int j=0;j<K;j++){
     77                 scanf("%d",&A.data[i][j]);
     78             }
     79         }
     80         for(int i=0;i<K;i++){
     81             for(int j=0;j<N;j++){
     82                 scanf("%d",&B.data[i][j]);
     83             }
     84         }
     85         gx.mul(C,B,A);
     86         D.n=D.m=C.n;
     87         for(int i=0;i<C.n;i++){
     88             for(int j=0;j<C.m;j++){
     89                 D.val[i][j]=C.data[i][j];
     90             }
     91         }
     92         D=D^(N*N-1);
     93         for(int i=0;i<C.n;i++){
     94             for(int j=0;j<C.m;j++){
     95                 C.data[i][j]=D.val[i][j];
     96             }
     97         }
     98         gx.mul(E,A,C);
     99         gx.mul(C,E,B);
    100         LL ans=0;
    101         for(int i=0;i<C.n;i++){
    102             for(int j=0;j<C.m;j++){
    103                 ans+=C.data[i][j]%6;
    104             }
    105         }
    106         printf("%I64d
    ",ans);
    107     }
    108     return 0;
    109 }
    View Code

     ZOJ Problem Set - 2974 Just Pour the Water http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1973

    nenucontest3,一个序列经过相同变化,变化10^9次,明显是构造矩阵,然后快速幂。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define mt(a,b) memset(a,b,sizeof(a))
     4 class Matrix { ///矩阵 下标0开始
     5     typedef double typev;///权值类型
     6     static const int MV=128;///矩阵长度
     7 //    static const int mod=10000;///%mod
     8     friend Matrix operator *(const Matrix &a,const Matrix &b) { ///矩阵乘法,必须a的列等于b的行
     9         Matrix ret;
    10         ret.n=a.n;
    11         ret.m=b.m;
    12         ret.zero();
    13         if(a.m==b.n) {
    14             for(int k=0; k<a.m; k++) {
    15                 for(int i=0; i<a.n; i++) {
    16                     if(a.val[i][k]) {
    17                         for(int j=0; j<b.m; j++) {
    18                             ret.val[i][j]+=a.val[i][k]*b.val[k][j];
    19 //                            ret.val[i][j]%=mod;///看具体需要
    20                         }
    21                     }
    22                 }
    23             }
    24         }
    25         return ret;
    26     }
    27     friend Matrix operator ^ (Matrix &a,int b) {///必须是n*n方阵才能快速幂
    28         Matrix ret;
    29         ret.n=ret.m=a.n;
    30         ret.unit();
    31         for(; b; a=a*a,b>>=1) {
    32             if(b&1) {
    33                 ret=ret*a;
    34             }
    35         }
    36         return ret;
    37     }
    38 public:
    39     int n,m;///n行m列
    40     typev val[MV][MV];
    41     void zero() {
    42         mt(val,0);
    43     }
    44     void unit() {
    45         zero();
    46         for(int i=0; i<MV; i++)
    47             val[i][i]=1;
    48     }
    49 } A;
    50 double a[128];
    51 int main(){
    52     int t,n;
    53     scanf("%d",&t);
    54     while(t--){
    55         scanf("%d",&n);
    56         for(int i=0;i<n;i++){
    57             scanf("%lf",&a[i]);
    58         }
    59         A.unit();
    60         int k,id,m;
    61         for(int i=0;i<n;i++){
    62             scanf("%d",&k);
    63             if(k) A.val[i][i]=0;
    64             for(int j=0;j<k;j++){
    65                 scanf("%d",&id);
    66                 A.val[id-1][i]=1.0/k;
    67             }
    68         }
    69         A.n=A.m=n;
    70         scanf("%d",&m);
    71         A=A^m;
    72         for(int i=0;i<n;i++){
    73             if(i) printf(" ");
    74             double sum=0;
    75             for(int j=0;j<n;j++){
    76                 sum+=A.val[i][j]*a[j];
    77             }
    78             printf("%.2f",sum);
    79         }
    80         puts("");
    81     }
    82     return 0;
    83 }
    View Code

    end

  • 相关阅读:
    Q群
    shell脚本写host类型executable
    Oracle EBS 基于Host(主机文件)并发程序的开发
    ORALCE存储之ROWID
    HOW TO LINK THE TRANSACTION_SOURCE_ID TO TRANSACTION_SOURCE_TYPE_ID
    查找Form文件
    ORACLE column_type_id与实际type的对应关系
    OAF jar包引用产生错误
    计算Trial Balance的新方法(转)
    如何访问到XtreemHost上的站点?
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/3950020.html
Copyright © 2020-2023  润新知