题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950
题目大意:给你f(1) = a , f(2 ) = b ,f(n) = 2*f(n-2) + f(n - 1) + n ^4(n >= 3);
思路: 当n >= 3 时 , 有f(n) = 2*f(n-2) + f(n-2) + ( n-1)^4 + 4 * ( n-1)^3 + 6 * (n-1)^3 + 4 *(n-1) + 1;
此时利用矩阵乘法可以构出7*7的矩阵, 转移就好了。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <stdlib.h>
#include <iomanip>
#include <fstream>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 105
#define MOD 1000000007
#define mod 2147493647
#define mem(a , b) memset(a , b , sizeof(a))
#define LL long long
#define ULL unsigned long long
#define FOR(i , n) for(int i = 1 ; i<= n ; i ++)
typedef pair<int , int> pii;
LL a , b , n;
struct mat
{
LL p[7][7] ;
};
mat mul(mat x , mat y)
{
mat res;
for(int i = 0 ; i < 7 ; i ++)
for(int j = 0 ; j < 7 ; j ++)
res.p[i][j] = (i == j);
for(int i = 0; i < 7 ; i ++)
{
for(int j = 0 ; j < 7 ; j ++)
{
LL ans = 0;
for(int k = 0 ; k < 7 ; k ++)
{
ans += (x.p[i][k] * y.p[k][j]) % mod;
ans %= mod;
}
res.p[i][j] = ans % mod;
}
}
return res;
}
mat Expow(mat x , int y)
{
mat res;
for(int i = 0 ; i < 7 ; i ++)
for(int j = 0 ; j < 7 ; j ++)
res.p[i][j] = (i == j);
while(y)
{
if(y & 1) res = mul(res , x);
x = mul(x , x);
y >>= 1;
}
return res;
}
int main()
{
int t;
scanf("%d" , &t);
for(int h = 1 ; h <= t ; h ++)
{
scanf("%lld %lld %lld" , &n , &a , &b);
if(n == 1)
{
printf("%lld\n" , a);
continue;
}
if(n == 2)
{
printf("%lld\n" , b);
continue;
}
mat m = { 0 , 1, 0 , 0 , 0 , 0 , 0 ,
2 , 1, 1 , 4 , 6 , 4 , 1 ,
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
};
m = Expow(m , n - 2);
LL ans = 0;
ans = (a * m.p[1][0] % mod + b * m.p[1][1] % mod) % mod;
ans += ((((m.p[1][2] * 16 % mod + m.p[1][3] * 8 )% mod + m.p[1][4] * 4 )% mod + m.p[1][5] * 2 )% mod + m.p[1][6]) % mod;
printf("%lld\n" , ans % mod);
}
return 0;
}