Matrix Power Series 题解(二分+矩阵快速幂)

题目链接

题目大意

计算(a^1+a^2+...+a^k)

(kleq10^9,szleq30)

(a)是矩阵

题目思路

要利用二分思想,感觉其实是分治的思想

我们先想一下(a^1+a^2+a^3+a^4+a^5+a^6)

这个式子怎么求

(a^1+a^2+a^3+a^4+a^5+a^6=(1+a^3)(a^1+a^2+a^3))

那么你就可以如何写了

(k)为奇数时

(sum_{i = 1}^k A^i = sum_{i = 1}^{k -1} A^i + A^{k })

(k)为偶数时

(sum_{i = 1}^k = sum_{i = 1}^{k / 2} A^i + A^{k / 2}(sum_{i = 1}^{k / 2}A^i))

代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=31,inf=0x3f3f3f3f;
const double eps=1e-6;
int n,k,mod;
struct matrix{
    int a[maxn][maxn];
}base,basetemp,ans,zero;
matrix mul(matrix a,matrix b){
    matrix temp;
    memset(temp.a,0,sizeof(temp.a)); //一定1要清空
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                temp.a[i][k]+=(a.a[i][j])*(b.a[j][k]);
                temp.a[i][k]%=mod;
            }
        }
    }
    return temp;
}
matrix add(matrix a,matrix b){
    matrix temp;
    memset(temp.a,0,sizeof(temp.a)); //一定1要清空
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            temp.a[i][j]=(a.a[i][j]+b.a[i][j])%mod;
        }
    }
    return temp;
}
matrix qpow(ll n,ll b){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            ans.a[i][j]=(i==j);
            base.a[i][j]=basetemp.a[i][j];
        }
    }
    while(b){
        if(b&1){
            ans=mul(ans,base);
        }
        base=mul(base,base);
        b=b>>1;
    }
    return ans;
}
matrix dfs(int x){
    if(x==0){
        return zero;
    }
    if(x%2==1){
        matrix temp1=qpow(n,x);
        x--;
        matrix temp2=dfs(x);
        matrix tempsum=add(temp1,temp2);
        return tempsum;
    }else{
        matrix temp1=qpow(n,x/2);
        for(int i=1;i<=n;i++){
            temp1.a[i][i]=(temp1.a[i][i]+1)%mod;
        }
        matrix temp2=dfs(x/2);
        matrix tempsum=mul(temp1,temp2);
        return tempsum;
    }
}
signed main(){
    scanf("%d%d%d",&n,&k,&mod);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&basetemp.a[i][j]);
        }
    }
    matrix pr=dfs(k);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            printf("%d%c",pr.a[i][j],j==n?'
':' ');
        }
    }
    return 0;
}

不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/15181459.html