洛谷 P1939 【模板】矩陣加速(數列)——————矩陣快速冪(水題)
阿新 • • 發佈:2018-12-13
P1939 【模板】矩陣加速(數列)
題目描述
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a數列的第n項對1000000007(10^9+7)取餘的值。
輸入輸出格式
輸入格式:
第一行一個整數T,表示詢問個數。
以下T行,每行一個正整數n。
輸出格式:
每行輸出一個非負整數表示答案。
輸入輸出樣例
輸入樣例#1: 3 6 8 10
輸出樣例#1:
4 9 19
說明
對於30%的資料 ;
對於60%的資料 ;
對於100%的資料 ;
構造矩陣 所以,我們這樣的話
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 4;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
struct mat{ll m[MAXN][MAXN]; } ;
ll N;
inline mat mul(mat a,mat b)
{
mat tmp;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
{
tmp.m[i][j]=0;
for(int k=1;k<=N;k++)
tmp.m[i][j]=(tmp.m[i][j]+a.m[i][k]*b.m[k][j]+MOD)%MOD;
}
return tmp;
}
inline mat pow_mod(mat a,ll n)
{
mat ans;
memset(ans.m,0,sizeof(ans.m));
for(int i=1;i<=N;i++)
ans.m[i][i]=1;
while(n)
{
if(n&1) ans=mul(ans,a);
a=mul(a,a);
n>>=1;
}
return ans;
}
int main()
{
ll n;
N=3;
mat a,b;
memset(a.m,0,sizeof(a.m));
memset(b.m,0,sizeof(b.m));
a.m[1][1]=1;
a.m[2][1]=1;
a.m[3][1]=1;
b.m[1][1]=1;b.m[1][3]=1;
b.m[2][1]=1;
b.m[3][2]=1;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld",&n);
if(n<=3)//之前沒寫這個,TLE了好幾次
{
printf("1\n");
continue;
}
mat c=pow_mod(b,n-2);
mat d=mul(c,a);
printf("%lld\n",d.m[2][1]);
}
return 0;
}