裴波拉契數列III
阿新 • • 發佈:2020-12-21
技術標籤:矩陣乘法
Description
求數列f[n]=f[n-1]+f[n-2]+1的第N項.f[1]=1,f[2]=1.
Input
n(1<n<2^31-1)
Output
第N項的結果 mod 9973
Sample Input
12345
Sample Output
8932
思路:
仿照前例,考慮1×3的矩陣【f[n-2],f[n-1],1】,
希望求得某3×3的矩陣A,使得此1×3的矩陣乘以A得到矩陣:
【f[n-1],f[n],1】=【f[n-1],f[n-1]+f[n-2]+1,1】
容易構造出這個3×3的矩陣A,即:
#include <cstring>
#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
const ll Mod = 9973;
struct node
{
ll x, y, a[40][40];
} A, B, C;
ll n;
node operator *(node x, node y) //矩陣乘法
{
node ans;
memset(ans.a, 0, sizeof(ans.a));
ans.x = x.x, ans.y = y.y;
for(ll k = 1; k <= x.y; k++)
for(ll i = 1; i <= x.x; i++)
for(ll j = 1; j <= y.y; j++)
ans.a[i][j] = (ans.a[i][j] + x.a[i][k] * y.a[k][j] % Mod) % Mod;
return ans;
}
void ksm(ll k) //單位矩陣的乘法結合律
{
if(k == 1) {C = B; return ;}
ksm(k >> 1);
C = C * C;
if(k & 1) C = C * B;
}
int main()
{
scanf("%lld", &n);
if(n < 3) {printf("1\n"); return 0;}
A.a[1][2] = A.a[1][1] = A.a[1][3] = 1, A.x = 1; A.y = 3;
B.a[1][2]= B.a[2][2] = B.a[3][2] = B.a[2][1] = B.a[3][3] = 1, B.x = 3, B.y = 3; //構造單位矩陣
ksm(n - 1), C = A * C;
printf("%lld", C.a[1][1] % Mod);
return 0;
}