hdu5950

Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers a and b on a blackboard. And then, the cows would say their identity number one by one. The first cow says the first number a and the second says the second number b. After that, the i-th cow says the sum of twice the (i-2)-th number, the (i-1)-th number, and
i
4
. Now, you need to write a program to calculate the number of the N-th cow in order to check if John’s cows can make it right.

题意:

:F(n) = 2*F(n-2) + F(n-1) + n4 和F(1) = a,F(2) = b;给定一个N,求F(N)
再来一道矩阵快速幂吧~~出现n4考虑((n-1)+1)4。。。。二项式定理。。。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const long long MOD = 2147493647;
struct Matrix{
    long long m[7][7];
};
long long aa,bb,n;

Matrix Mul(Matrix a ,Matrix b){
    Matrix tmp;
    memset(tmp.m,0,sizeof(tmp.m));
    for(int i =  0 ; i < 7 ; i++)
        for(int j = 0 ; j < 7 ;j++)
            for(int k = 0 ; k < 7 ; k++)
                tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j])%MOD;
    return tmp;
}

Matrix qpow(Matrix a,long long n){
    Matrix tmp;
    memset(tmp.m,0,sizeof(tmp.m));
    for(long long i = 0 ; i < 7 ; i++)  tmp.m[i][i] = 1;
        while(n){
            if(n & 1)   tmp = Mul(tmp,a);
            n >>= 1;
            a = Mul(a,a);
        }
    return tmp;
}

void sov(){
    Matrix tmp;
    memset(tmp.m,0,sizeof(tmp.m));
    tmp.m[0][0] = tmp.m[0][2] = tmp.m[0][6] = tmp.m[1][0] = 1;
    for(int i = 2 ; i <= 6 ; i++)   tmp.m[i][6] = tmp.m[i][i] = 1;
    tmp.m[0][3] = tmp.m[0][5] = tmp.m[2][3] = tmp.m[2][5] = 4;
    tmp.m[0][4] = tmp.m[2][4] = 6;
    tmp.m[3][5] = tmp.m[3][4] = 3;
    tmp.m[4][5] = tmp.m[0][1] = 2;
    tmp = qpow(tmp,n-2);
    long long ans;
    ans = (tmp.m[0][0] * bb)%MOD;
    ans = (ans+tmp.m[0][1] *aa)%MOD;
    ans = (ans+tmp.m[0][2] *16)%MOD;
    ans = (ans+tmp.m[0][3] * 8)%MOD;
    ans = (ans+tmp.m[0][4] * 4)%MOD;
    ans = (ans+tmp.m[0][5] * 2)%MOD;
    ans = (ans+tmp.m[0][6])%MOD;
    cout << ans<<endl;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        cin>> n>> aa >> bb;
        if(n == 1)  cout << aa<<endl;
        else if( n== 2) cout << bb<<endl;
        else{
            sov();
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值