洛谷 P1939 【模板】矩阵加速(数列)
Description
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
Input
第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。
Output
- 每行输出一个非负整数表示答案。
Sample Input
3
6
8
10
Sample Output
4
9
19
Data Size
对于30%的数据 n<=100;
对于60%的数据 n<=2*10^7;
对于100%的数据 T<=100,n<=2*10^9;
题解:
- 一道矩阵加速。
- 水题直接切掉了
#include <iostream>
#include <cstdio>
#include <cstring>
#define mod 1000000007
#define LL long long
using namespace std;
struct Obj
{
LL m[4][4];
Obj () {memset(m, 0, sizeof(m));}
};
LL T, n;
Obj mul(Obj a, Obj b)
{
Obj c;
for(LL i = 1; i <= 3; i++)
for(LL j = 1; j <= 3; j++)
for(LL k = 1; k <= 3; k++)
c.m[i][j] += (a.m[i][k] % mod * b.m[k][j] % mod) % mod,
c.m[i][j] %= mod;
return c;
}
Obj power(Obj a, LL b)
{
Obj d; d.m[1][1] = d.m[2][2] = d.m[3][3] = 1;
Obj r = d, base = a;
while(b)
{
if(b & 1) r = mul(r, base);
base = mul(base, base);
b >>= 1;
}
return r;
}
int main()
{
cin >> T;
while(T--)
{
cin >> n;
if(n <= 3) {cout << 1 << endl; continue;}
Obj t1;
t1.m[1][1] = t1.m[1][3] = t1.m[2][1] = t1.m[3][2] = 1;
t1 = power(t1, n - 3);
Obj t2, ans; t2.m[1][1] = t2.m[2][1] = t2.m[3][1] = 1;
for(LL i = 1; i <= 3; i++)
for(LL j = 1; j <= 1; j++)
for(LL k = 1; k <= 3; k++)
ans.m[i][j] += (t1.m[i][k] % mod * t2.m[k][j] % mod) % mod,
ans.m[i][j] %= mod;
cout << ans.m[1][1] << endl;
}
return 0;
}