Stay Hungry,Stay Foolish!

A. Plant

A. Plant

https://codeforces.com/contest/185/problem/A

 

思路

发现状态转移矩阵M

        目标状态-上三角  目标状态-下三角

源状态-上三角  3          1

源状态-下三角  1          3

 

初始状态为向量V

初始状态-上三角  1          

初始状态-下三角  0

     

过第一年V的转变为 MV     

过第二年V的转变为 MMV

.....

 

关键点在于计算矩阵的幂级数pow(M, n)

需要重载乘法运算符。

 

普通数的快速幂见:

https://www.cnblogs.com/lightsong/p/16953894.html

Code

https://codeforces.com/contest/185/submission/197058183

#include <bits/stdc++.h>
using namespace std;
const long long mod=1000000007;
#define ll long long

struct M{
    ll m[2][2];
};

M operator*(M a,M b){
    M ans={{0}};
    
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            for(int k=0;k<2;k++){
                ans.m[i][j]+=a.m[i][k]*b.m[k][j];
                ans.m[i][j]%=mod;
            }
        }
    }
    return ans;
} 
M ksm(M a,ll b){
    M ans{.m={{1,0},{0,1}}};
    while (b>0){
        if(b&1)ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
} 
int main(){
    ll a;
    cin>>a;
//    M s,tmp;
    M tmp{.m={{3,1},{1,3}}};
    M s{.m={{1,0},{0,0}}};
//    M ans=tmp*s;
    M ans=ksm(tmp,a)*s;
    cout<<ans.m[0][0]<<endl;
//    cout<<ans.m[0][0]<<" "<<ans.m[0][1]<<endl<<ans.m[1][0]<<" "<<ans.m[1][1]<<endl;;
}

 

posted @ 2023-03-13 09:20  lightsong  阅读(20)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel