题目描述
存在如下递推式:
F(n+1)=A1*F(n)+A2*F(n-1)+...+An*F(1)
求第K项的值对1000000007取模的结果
输入
单组测试数据
第一行输入两个整数 n , k (1<=n<=100,n<k<=10000000000)
第二行输入 n 个整数 F(1) F(2) ... F(n)
第三行输入 n 个整数A1 A2 ... An
输出
输出一个整数
样例输入
2 3
1 2
3 4
样例输出
10
提示
官方题解:
斐波拉契数列变形题,利用递推式构造矩阵,利用矩阵快速幂求解,注意使用滚动数组进行优化,否则可能会TLE。时间复杂度n^3logk。
不过我并没有用滚动数组而是加了一个剪枝就过了。
这是我构造的矩阵(当n=3时):
#include <cstdio>
#include <cstring>
#define MOD 1000000007
using namespace std;
struct jj
{
long long a[100][100];
}x,t;
struct jj multiply(int n,struct jj a,struct jj b)
{
int i,i1,i2;
struct jj key;
memset(key.a,0,sizeof(key.a));
for(i=0;n>i;i++)
{
for(i1=0;n>i1;i1++)
{
if(a.a[i1][i]==0) //剪枝
{
continue;
}
for(i2=0;n>i2;i2++)
{
key.a[i1][i2]=(key.a[i1][i2]+(a.a[i1][i]*b.a[i][i2])%MOD)%MOD;
}
}
}
return key;
}
long long f(int n,long long k)
{
while(k!=0)
{
if(k%2==1)
{
x=multiply(n,t,x);
}
t=multiply(n,t,t);
k=k/2;
}
return x.a[0][0];
}
int main()
{
int n,i;
long long k;
scanf("%d %lld",&n,&k);
k=k-n;
memset(x.a,0,sizeof(x.a));
memset(t.a,0,sizeof(t.a));
for(i=0;n>i;i++)
{
scanf("%lld",&x.a[n-i-1][0]);
}
for(i=0;n>i;i++)
{
scanf("%lld",&t.a[0][i]);
if(i!=0)
{
t.a[i][i-1]=1;
}
}
printf("%lld\n",f(n,k));
return 0;
}
/**************************************************************
Problem: 1768
Code Length: 1363 B
Language: C++
Result: 正确
Time:556 ms
Memory:1212 kb
****************************************************************/