Description
给你一个递推公式:
f(x)=a*f(x-2)+b*f(x-1)+c
并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值。
注意:-1对3取模后等于2
Input
第一行是一个整数T,表示测试数据的组数(T<=10000) 随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值。 其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=100000000 (10^9)
Output
输出f(n)对1000007取模后的值
Sample Input
2
1 1 1 1 0 5
1 1 -1 -10 -100 3
Sample Output
5
999896
Hint
题意
转化矩阵
⎡⎣⎢b10a00c01⎤⎦⎥
初始矩阵
⎡⎣⎢f2f11⎤⎦⎥
题解:
wa在long long 以及n为1,2的特判
AC代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
int n;
struct mat{LL rix[3][3];};
const LL mod = 1000007;
mat mul(mat a,mat b){
mat c;
for (int i = 0;i < 3; ++i) for (int j = 0; j < 3; ++j) c.rix[i][j] = 0;
for (int i = 0;i < 3; ++i){
for (int j = 0;j < 3; ++j){
for (int k = 0;k < 3; ++k){
c.rix[i][j] += a.rix[i][k]*b.rix[k][j];
c.rix[i][j] = c.rix[i][j]%mod + mod;
c.rix[i][j] %= mod;
}
}
}
return c;
}
mat q_mod(mat a,LL b){
mat tmp;
for (int i = 0;i < 3; ++i) for (int j = 0;j < 3; ++j) if (i!=j) tmp.rix[i][j] = 0; else tmp.rix[i][j] = 1;
while (b){
if (b&1) tmp = mul(tmp,a);
a = mul(a,a);
b>>=1;
}
return tmp;
}
int main(){
int t;
scanf("%d",&t);
while (t--){
LL st[3][1];
LL ans[3][1];
memset(ans,0,sizeof(ans));
memset(st,0,sizeof(st));
mat tt;
LL f1,f2,x,y,z;
for (int i = 0;i < 3; ++i) for (int j = 0; j < 3; ++j) tt.rix[i][j] = 0;
tt.rix[1][0] = tt.rix[2][2] = 1;
scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&x,&y,&z,&n);
tt.rix[0][0] = y; tt.rix[0][1] = x; tt.rix[0][2] = z;
st[0][0] = f2; st[1][0] = f1; st[2][0] = 1;
if (n==1)
{
printf("%lld\n",(f1+mod)%mod);
continue;
}
if (n==2)
{
printf("%lld\n",(f2+mod)%mod);
continue;
}
mat ed = q_mod(tt,n-1);
for (int i = 0;i < 3; ++i){
for (int j = 0;j < 1; ++j){
for (int k = 0;k < 3; ++k){
ans[i][j] += ed.rix[i][k]*st[k][j];
ans[i][j] = ans[i][j]%mod+mod;
ans[i][j] %= mod;
}
}
}
printf("%lld\n",ans[1][0]);
}
return 0;
}