3976: 妈妈,我想学这个
题目:
现在有个难题摆在小明面前,an=an-1+an-2+an-3 已知a1,a2,a3求出第n个数的值,小明算了好久也没有算出答案来
小明正抓耳挠腮时他的同学凑过来一看,说这题很简单嘛,只要先这样,再这样,最后再这样。。。
答案就出来了,小明十分的羡慕,回到家中就向妈妈说,我也想学,妈妈只说了:不,你学不会!
小明只好向你求助,让你来实现他的想法。
输入
输入1个数T,表示有T组样例。
之后T行,每行4个整数分别代表a1,a2,a3,n (输入的所有数据全在int范围内)
输出
由于an可能非常大,输出时对20190809取余(结果为负则再加上20190809转为正数输出),每组数据输出1行。
样例输入
3
1 1 1 5
1 2 3 4
-1 -2 3 8
样例输出
5
6
10
代码:
#include<stdio.h>
#define M 20190809
long long t,a[3],n;
int main()
{
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld%lld%lld",&a[0],&a[1],&a[2],&n);
for(long long i=0;i<=2;i++)
a[i]=(a[i]%M+M)%M;
for(long long i=3;i<n;++i)
a[i%3]=(a[0]+a[1]+a[2])%M;
printf("%lld\n",a[(n-1)%3]);
}
return 0;
}
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
typedef long long ll;
const ll mod = 20190809;
struct node{
ll num[3][3];
}A, B;
void init(){
for(ll i=0; i<3; ++i){
for(ll j=0; j<3; ++j){
A.num[i][j] = 1;
}
}
A.num[1][1] = A.num[1][2] = A.num[2][0] = A.num[2][2] = 0;
}
node mul(node AA, node BB){
node C;
for(ll i=0; i<3; ++i){
for(ll j=0; j<3; ++j){
C.num[i][j] = 0;
for(ll k=0; k<3; ++k){
C.num[i][j] += AA.num[i][k]*BB.num[k][j];
C.num[i][j] = (C.num[i][j]%mod+mod)%mod;
}
}
}
return C;
}
ll Pow(ll n, ll a1, ll a2, ll a3){
B.num[0][0] = a3;
B.num[1][0] = a2;
B.num[2][0] = a1;
while(n > 0){
if(n&1){
B = mul(A, B);
}
A = mul(A, A);
n = n>>1;
}
return (B.num[0][0]%mod+mod)%mod;
}
int main(){
ll t, a1, a2, a3, n;
scanf("%lld", &t);
while(t--){
init();
scanf("%lld%lld%lld%lld", &a1, &a2, &a3, &n);
if(n == 1){
printf("%lld\n", (a1%mod+mod)%mod);
continue;
}
if(n == 2){
printf("%lld\n", (a2%mod+mod)%mod);
continue;
}
if(n == 3){
printf("%lld\n", (a3%mod+mod)%mod);
continue;
}
ll ans = Pow(n-3, a1, a2, a3);
printf("%lld\n", ans);
}
return 0;
}