递推 +二项式定理(矩阵快速幂)

https://nanti.jisuanke.com/t/A2060

题意:第一个数为f[1] = a ,f[2] = b . 递推式:f[n] = f[n-1] + 2*f[n-2] + n4 . 求f[n]%2147493647.

数据:N,a,b<231

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
#include<iostream>
#include<map>
#define inf 0x3f3f3f3f
#define ll long long
#define maxx 5000000
#define mod 2147493647//注意这是一个ll型的数,会爆int
using namespace std;
struct node
{
    ll a[7][7] ;
    node()
    {memset(a , 0 , sizeof(a));}
};

node mul(node A , node B)
{
    node C;
    for(int i = 0 ; i < 7 ; i++)
    {
        for(int j = 0 ; j < 7 ; j++)
        {
            for(int k = 0 ; k < 7 ; k++)
            {
                C.a[i][j] = (C.a[i][j] % mod + A.a[i][k] * B.a[k][j] % mod) % mod ;
            }
        }
    }
    return C;
}

node quickpow(node A,  ll t)
{
    node ans ;
    for(int i = 0 ; i < 7 ; i++)
        ans.a[i][i] = 1 ;
    while(t)
    {
        if(t&1)
        {
            ans = mul(ans , A);
        }
        t >>= 1 ;
        A = mul(A, A);
    }
    return ans ;
}

ll a[7][7] = {{1,2,1,4,6,4,1},
              {1,0,0,0,0,0,0},
              {0,0,1,4,6,4,1},
              {0,0,0,1,3,3,1},
              {0,0,0,0,1,2,1},
              {0,0,0,0,0,1,1},
              {0,0,0,0,0,0,1}};

int main()
{
    cout << mo << endl ;
    int t ;
    scanf("%d" , &t);
    node A ,  B , C ;
    for(int i = 0 ; i < 7 ; i++)
    {
        for(int j = 0 ; j < 7 ; j++)
        {
            A.a[i][j] = a[i][j];
        }
    }
    while(t--)
    {
        ll  n ,  a , b ;
        scanf("%lld%lld%lld" , &n , &a , &b);
        ll c = a*2%mod + b%mod + 3*3*3*3;
        if(n == 1){
            cout << a << endl;
            continue ;
        }
        else if(n == 2)
        {
            cout << b << endl ;
            continue ;
        }
        else if(n == 3)
        {
            cout << c%mod << endl ;
            continue ;
        }
        B.a[0][0] = c%mod , B.a[1][0] = b%mod;
        B.a[2][0] = 81 , B.a[3][0] = 27 , B.a[4][0] = 9;
        B.a[5][0] = 3 , B.a[6][0] = 1 ;
        C = mul(quickpow(A , n-3) , B);
        cout << C.a[0][0]%mod << endl ;
    }
    return 0 ;
}

猜你喜欢

转载自www.cnblogs.com/nonames/p/12187448.html