• POJ3233 Matrix Power Series (等比矩阵求和)


    题意::求等比矩阵和:S = A + A2 + A3 + … + Ak

    参考巨佬们的经典算法( 接近模板 )

    :::构造矩阵  E为单位矩阵

     看不明白的可以手模一下,

    答案就是 右上角子矩阵减一个同阶单位矩阵

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=65;
     5 
     6 int n,MOD,k;
     7 struct mat
     8 {
     9     int a[maxn][maxn];
    10     mat(){
    11         memset(a,0,sizeof(a));
    12     }
    13 };
    14 mat mul(mat x,mat y)
    15 {
    16     mat res;
    17     for(int i=0;i<n;i++)
    18     {
    19         for(int j=0;j<n;j++)
    20         {
    21             for(int k=0;k<n;k++)
    22             {
    23                 res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j]%MOD)%MOD;
    24             }
    25         }
    26     }
    27     return res;
    28 }
    29 mat qpow(mat x,int p)
    30 {
    31     mat res;
    32     for(int i=0;i<n;i++){
    33         res.a[i][i]=1;
    34     }
    35     while(p)
    36     {
    37         if(p&1){
    38             res=mul(res,x);
    39         }
    40         x=mul(x,x);
    41         p>>=1;
    42     }
    43     return res;
    44 }
    45 int main()
    46 {
    47     scanf("%d%d%d",&n,&k,&MOD);
    48     mat ans;
    49     for(int i=0;i<n;i++){
    50         for(int j=0;j<n;j++){
    51             scanf("%d",&ans.a[i][j]);
    52             ans.a[i][j]%=MOD;
    53         }
    54     }
    55     for(int i=n;i<(n<<1);i++){
    56         ans.a[i-n][i]=ans.a[i][i]=1;
    57     }
    58     n=n<<1;
    59     ans=qpow(ans,k+1);
    60     n=n>>1;
    61     for(int i=0;i<n;i++)
    62     {
    63         ans.a[i][i+n]=(ans.a[i][i+n]-1+MOD)%MOD;
    64     }
    65     for(int i=0;i<n;i++)
    66     {
    67         for(int j=n;j<(n<<1);j++)
    68         {
    69             printf("%d ",ans.a[i][j]);
    70         }
    71         printf("
    ");
    72     }
    73     return 0;
    74 }
    View Code

     矩阵快速幂+二分

    S = A + A2 + A3 + … + Ak

    对于整数而言::

    n为偶数时::S[n]=(a^(n/2)+1)*S[n/2]

    n为奇数时::S[n]=(a^(n/2+1)+1)*S[n/2]+(a^(n/2)+1);

    对于矩阵也同样适用 ,当n==0时 S为单位矩阵;

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=65;
     5 
     6 int n,MOD,k;
     7 struct mat
     8 {
     9     int a[maxn][maxn];
    10     mat(){
    11         memset(a,0,sizeof(a));
    12     }
    13 };
    14 mat mul(mat x,mat y)
    15 {
    16     mat res;
    17     for(int i=0;i<n;i++){
    18         for(int j=0;j<n;j++){
    19             for(int k=0;k<n;k++){
    20                 res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j]%MOD)%MOD;
    21             }
    22         }
    23     }return res;
    24 }
    25 mat add(mat x,mat y)
    26 {
    27     mat res;
    28     for(int i=0;i<n;i++){
    29         for(int j=0;j<n;j++){
    30             res.a[i][j]=(res.a[i][j]+x.a[i][j]+y.a[i][j])%MOD;
    31         }
    32     }
    33     return res;
    34 }
    35 mat qpow(mat x,int p)
    36 {
    37     mat res;
    38     for(int i=0;i<n;i++){
    39         res.a[i][i]=1;
    40     }
    41     while(p){
    42         if(p&1){
    43             res=mul(res,x);
    44         }
    45         x=mul(x,x);
    46         p>>=1;
    47     }
    48     return res;
    49 }
    50 mat solve(mat x,int k)
    51 {
    52     if(k==1){
    53         return x;
    54     }
    55     mat t=solve(x,k/2);
    56     if(k&1){
    57         mat res=qpow(x,k/2+1);
    58         t=add(add(mul(res,t),t),res);
    59     }
    60     else{
    61         mat res=qpow(x,k/2);
    62         t=add(mul(res,t),t);
    63     }
    64     return t;
    65 }
    66 
    67 int main()
    68 {
    69     scanf("%d%d%d",&n,&k,&MOD);
    70     mat ans;
    71     for(int i=0;i<n;i++){
    72         for(int j=0;j<n;j++){
    73             scanf("%d",&ans.a[i][j]);
    74             ans.a[i][j]%=MOD;
    75         }
    76     }
    77     ans=solve(ans,k);
    78     for(int i=0;i<n;i++){
    79         for(int j=0;j<n;j++){
    80             printf("%d ",ans.a[i][j]);
    81         }printf("
    ");
    82     }
    83     return 0;
    84 }
    View Code
    纵使单枪匹马,也要勇闯天涯
  • 相关阅读:
    使用Random类生成指定范围的随机数
    js ==和===的区别
    js中的undefined
    js的split函数
    springboot发送邮件
    1032 Sharing (25分)(数组链表)
    1031 Hello World for U (20分)
    1030 Travel Plan (30分)(dijkstra 具有多种决定因素)
    1029 Median (25分)
    1026 Table Tennis (30分)
  • 原文地址:https://www.cnblogs.com/sj-gank/p/11771343.html
Copyright © 2020-2023  润新知