Description
zyf总是有很多奇异的想法,他最近常常幻想着以后能开这么一个工厂,可以把前三天里生产出来的东西拿到今天来拼在一起作为今天生产的东西。假如前三天生产出来的产品数分别是x,y,z,那么今天就能生产出x+y+z个。这样一来只要前三天的投入,接下来的工厂每一天都是0成本运作,但产品数却在极速增加,相当暴利。
当然,为了防止地球被破坏,为了维护世界的和平,zyf是不会让工厂每天生产出来的东西超过1000000006个的,如果超过了,就不停减去1000000007,减到不超过为止。
现在zyf想知道如果第一、二、三天分别生产a,b,c个产品的话,第n天会生产出多少产品呢?
Input
输入数据的第一行case数。
接下来每一行都有四个数字a,b,c,n(1<=a,b,c,n<=10^9),意义如上文.
接下来每一行都有四个数字a,b,c,n(1<=a,b,c,n<=10^9),意义如上文.
Output
对于每个case输出一行,第n天生产的产品数。
Sample Input
2
1 2 3 4
1 1 1 5
1 2 3 4
1 1 1 5
Sample Output
6
5
5
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define div 1000000007
/*
A=
0 0 1
1 0 1
0 1 1
*/
// (a[n],a[n+1],a[n+2])*A=(a[n+1],a[n+2],a[n+3])
//然后求A的n 次方
void multiply(long long a[][4],long long b[][4]) //两个矩阵相乘
{
long long c[4][4]={0};
int i ,j,k;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
for(k=0;k<3;k++)
c[i][j]+=(a[i][k]%div)*(b[k][j]%div);
for(i=0;i<3;i++)
for(j=0;j<3;j++)
a[i][j]=c[i][j]%div;
}
void power(long long a[][4],int n) //一个矩阵的n次方
{
int i ,j;
long long b[4][4];
memcpy(b,a,sizeof(b));
if(n>1)
{
if(n%2) //n为奇数,a^n=a^(n-1)/2*a^(n-1)/2*a;
{
power(a,(n-1)/2);
multiply(a,a);
multiply(a,b);
}
else //n为偶数 a^n=a^(n-1)/2*a^(n-1)/2
{
power(a,n/2);
multiply(a,a);
}
}
}
int main()
{
int a[4]={0};
int n;
long long ans;
int i ,j;
int p=0,t;
long long matrix1[4][4]={{0,0,1},{1,0,1},{0,1,1}};
long long matrix[4][4]={0};
scanf("%d",&t);
while(p++!=t)
{
ans=0;
memcpy(matrix,matrix1,sizeof(matrix1));
for(i=0;i<3;i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&n);
if(n<4) //n<4则直接输出前三个的 一个
{
ans=a[n-1];
}
else
{
power(matrix,n-3); //求出矩阵的n 次方
for(i=0;i<3;i++)
ans+=matrix[i][2]*a[i]%div;
}
printf("%lld\n",ans%div);
}
return 0;
}
我这个写的是3个的,2个的更简单点的