[行列の乗算] [SSL1529]フィボナッチ数列Ⅱ
トピック
1,123,581,321,345,589,144のような形...列の数、必要な列の数nnのPei Bo Laqinアイテム。
入る
nn n(1 〈nnn〈2 ^ 31)
出力
ペイボラチーの一連の数NNnアイテムmodmodm o d 10000;
サンプル
入力
123456789
出力
4514
問題解決のアイデア
行列の乗算
2つの行列AAA、BBBにtmtmを掛けたもの
生成物の長さのT mがあるAAAの長さと幅はBBですBの広い
AA
図に示すように、 Aの最初の行の数値とBの最初の列の数値の積の合計が、積の最初の行と最初の列の数値になります。
この質問の書き方は
、f [n] = f [n − 1] + f [n − 2] f [n] = f [n-1] + f [n-2]であるとされています。f [ n ]=f [ n−1 ]+f [ n−2 ] f [n + 1] f [n +1]
が必要な場合f [ n+1 ]
即f [n + 1] = f [n] + f [n − 1] f [n + 1] = f [n] + f [n-1]f [ n+1 ]=f [ n ]+f [ n−1 ]
展開Fが[N + 1] = F [N - 1] + F [N - 2] + F [N - 1] F [N + 1] = F [N-1] + F [N-2] + f [n-1]f [ n+1 ]=f [ n−1 ]+f [ n−2 ]+f [ n−1 ]
現在のf [n − 1] f [n-1]を格納するための回答行列を作成できます。f [ n−1 ]およびf [n] f [n]f [ n ]
現在のf [n]は次のf [n − 1] f [n-1]です。f [ n−1 ]
そして次のf [n] f [n]f [ n ]は、現在のf [n]およびf [n − 1] f [n-1]です。f [ n−1 ]合計
は行列として構成できます。
タイトルでは、nnnは2 ^ 31であり、
高速指数を使用して解くことが考えられます。
コード
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int mo=10000;
long long n;
struct hhx{
long long n,m,h[5][5];
}a,b,x;
hhx operator * (hhx l,hhx y) //重新定义乘号
{
x.n=l.n,x.m=y.m;
memset(x.h,0,sizeof(x.h));
for (int k=1;k<=l.m;k++)
for (int i=1;i<=x.n;i++)
for (int j=1;j<=x.m;j++)
x.h[i][j]=(x.h[i][j]+l.h[i][k]*y.h[k][j]%mo)%mo;
return x;
}
void power(long long n) //快速幂
{
if (n & 1) a=a*b;
if (n==1) return;
b=b*b;
power(n/2);
}
int main()
{
a.n=1,a.m=2;
a.h[1][1]=a.h[1][2]=1;
b.n=2,b.m=2;
b.h[1][2]=b.h[2][1]=b.h[2][2]=1; //赋值
scanf("%lld",&n);
power(n-1);
printf("%lld",a.h[1][1]);
return 0;
}