您的位置:首页 > 其它

hdu 4686 矩阵乘法优化递推关系

2014-06-19 20:02 267 查看
这里有一份解题报告

解题报告

这是理论知识:

点我

最主要的是构造乘法矩阵,这个是通过递推关系得到的。

有了它,求数列的第n项可以在log(n)的时间里求出来。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
#include <map>
#include<vector>
#define maxn 1010
#define mod 1000000007
using namespace std;
typedef long long ll;
struct Matrix{
ll a[10][10];
}res,A,F,ans,temp;
Matrix mul(Matrix a,Matrix b){
memset(temp.a,0,sizeof(temp.a));
for(int i=0;i<5;++i){
for(int j=0;j<5;++j){
for(int k=0;k<5;++k){
temp.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod;
temp.a[i][j]%=mod;
}
}
}
return temp;
}
void quick_pow(ll k){
memset(res.a,0,sizeof(res.a));
for(int i=0;i<5;++i)res.a[i][i]=1;
while(k){
if(k&1)res = mul(res,A);
A = mul(A,A);
k>>=1;
}
}
int main (){
ll  a0,ax,ay;
ll b0,bx,by;
ll n;
ll f1,a1,b1,s0;
while(cin>>n){
cin>>a0>>ax>>ay;
cin>>b0>>bx>>by;
if(n==0){printf("0\n");continue;}
a1 = ((a0*ax)%mod+ay)%mod;
b1 = ((b0*bx)%mod+by)%mod;
f1 = (a1*b1)%mod;
s0 = (a0*b0)%mod;
memset(A.a,0,sizeof(A.a));
A.a[0][0]=(ax*bx)%mod;
A.a[1][0]=(ax*by)%mod;
A.a[2][0]=(ay*bx)%mod;
A.a[3][0]=(ay*by)%mod;
A.a[1][1]=ax%mod;
A.a[3][1]=ay%mod;
A.a[2][2]=bx%mod;
A.a[3][2]=by%mod;
A.a[3][3]=1;
A.a[0][4]=1;
A.a[4][4]=1;
memset(F.a,0,sizeof(F.a));
F.a[0][0]=f1%mod;
F.a[0][1]=a1%mod;
F.a[0][2]=b1%mod;
F.a[0][3]=1;
F.a[0][4]=s0%mod;
quick_pow(n-1);
ans=mul(F,res);
printf("%lld\n",(ans.a[0][4])%mod);
}
return 0;
}


View Code
PS:杭电不支持long long lld 输出,(╯‵□′)╯︵┻━┻
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: