1. 程式人生 > >HDU1757又是一道矩陣快速冪模板題

HDU1757又是一道矩陣快速冪模板題

ace define eof mem col 矩陣 重定向 target class

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1757

按照題目的要求構造矩陣

//Author: xiaowuga
//矩陣:
//a0 a1 a2 a3 a4 a5 a6 a7 a8 a9   9
// 1  0  0  0  0  0  0  0  0  0   8
// 0  1  0  0  0  0  0  0  0  0   7
// 0  0  1  0  0  0  0  0  0  0   6
// 0  0  0  1  0  0  0  0  0  0   5
// 0  0  0  0  1  0  0  0  0  0   4
// 0  0  0  0  0  1  0  0  0  0   3
// 0  0  0  0  0  0  1  0  0  0   2
// 0  0  0  0  0  0  0  1  0  0   1
// 0 0 0 0 0 0 0 0 1 0 0 #include <bits/stdc++.h> #define maxx INT_MAX #define minn INT_MIN #define inf 0x3f3f3f3f #define N 10 using namespace std; typedef long long ll; int k,MOD; int arr[N],f[N]; struct Matrix{ ll mat[N][N]; //重定向乘法 Matrix operator*(const Matrix &m)const{ Matrix tmp;
for(int i=0;i<N;i++) for(int j=0;j<N;j++){ tmp.mat[i][j]=0; for(int k=0;k<N;k++){ tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD; tmp.mat[i][j]%=MOD; } } return tmp; } }; ll POW(Matrix
&m,int k){ Matrix ans; memset(ans.mat,0,sizeof(ans.mat)); for(int i=0;i<N;i++) ans.mat[i][i]=1; k-=9; while(k){ if(k&1) ans=ans*m; k/=2; m=m*m; } ll sum=0; for(int i=0;i<N;i++){ sum+=ans.mat[0][i]*f[N-i-1]%MOD; sum%=MOD; } return sum; } void init(Matrix &m){ memset(m.mat,0,sizeof(m.mat)); for(int i=0;i<N;i++) m.mat[0][i]=arr[i]; for(int i=0;i<N-1;i++) m.mat[i+1][i]=1; for(int i=0;i<N;i++) f[i]=i; } int main() { ios::sync_with_stdio(false);cin.tie(0); Matrix m; while(cin>>k>>MOD){ for(int i=0;i<N;i++) cin>>arr[i]; init(m); if(k<10) cout<<k%MOD<<endl; else cout<<POW(m,k)<<endl; } return 0; }

HDU1757又是一道矩陣快速冪模板題