【矩陣乘法】OpenJ_POJ - C17F - A Simple Math Problem
阿新 • • 發佈:2017-07-18
() sign pri space con class std name per
算(7+4*sqrt(3))^n的整數部分(mod 1e9+7)。
容易想到矩乘快速冪,但是怎麽算整數部分呢?
(7+4*sqrt(3))^n一定可以寫成a+b*sqrt(3),同理(7-4*sqrt(3))^n一定可以寫成a-b*sqrt(3),於是,
(7+4*sqrt(3))^n
= (7+4*sqrt(3))^n + (7-4*sqrt(3))^n - (7-4*sqrt(3))^n
= 2*a - (7-4*sqrt(3))^n/*必然小於1*/
所以其整數部分 = 2*a - 1
#include<vector> #include<cstdio> using namespace std; typedef long long ll; #define MOD 1000000007ll typedef vector<ll> vec; typedef vector<vec> mat; mat I; mat operator * (const mat &a,const mat &b){ mat c(a.size(),vec(b[0].size())); for(int i=0;i<a.size();++i){ for(int k=0;k<b.size();++k){ for(int j=0;j<b[0].size();++j){ c[i][j]=(c[i][j]+a[i][k]*b[k][j]%MOD)%MOD; } } } return c; } mat Quick_Pow(mat a,ll p){ if(!p){ return I; } mat res=Quick_Pow(a,p>>1); res=res*res; if(p&1ll){ res=res*a; } return res; } int T,n; int main(){ // freopen("f.in","r",stdin); I.assign(2,vec(2)); for(int i=0;i<2;++i){ for(int j=0;j<2;++j){ if(i==j){ I[i][j]=1; } else{ I[i][j]=0; } } } mat A(2,vec(2)); A[0][0]=7; A[0][1]=12; A[1][0]=4; A[1][1]=7; mat B(2,vec(1)); B[0][0]=1; B[1][0]=0; scanf("%d",&T); for(;T;--T){ scanf("%d",&n); printf("%lld\n",((Quick_Pow(A,n)*B)[0][0]*2ll%MOD+MOD-1ll)%MOD); } return 0; }
【矩陣乘法】OpenJ_POJ - C17F - A Simple Math Problem