Recursive sequence HDU - 5950 (矩阵加速线性递推+矩阵快速幂)
矩阵加速的线形递推的裸题,难点就在于构造矩阵。
代码:
using namespace std;
const int MAXN=7;
int T;
ll a,b,n;
typedef struct{
ll mp[MAXN][MAXN];
void init(){
mem(mp,0);
for(int i=0;i<MAXN;i++){
mp[i][i]=1;
}
}
}matrix;
matrix pp={
1,1,0,0,0,0,0,
2,0,0,0,0,0,0,
1,0,1,0,0,0,0,
4,0,4,1,0,0,0,
6,0,6,3,1,0,0,
4,0,4,3,2,1,0,
1,0,1,1,1,1,1
};
matrix multi(matrix a,matrix b)
{
matrix res;
for(int i=0;i<MAXN;i++){
for(int j=0;j<MAXN;j++){
res.mp[i][j]=0;
for(int k=0;k<MAXN;k++){
res.mp[i][j]+=(a.mp[i][k]*b.mp[k][j])%MOD;
res.mp[i][j]=res.mp[i][j]%MOD;
}
}
}
return res;
}
matrix fastm(matrix a,ll x)
{
matrix res;
res.init();
while(x){
if(x&1){
res=multi(res,a);
}
x>>=1;
a=multi(a,a);
}
return res;
}
int main()
{
cin>>T;
while(T--){
scanf("%lld%lld%lld",&n,&a,&b);
if(n==1){
printf("%lld\n",a);
}else if(n==2){
printf("%lld\n",b);
}else{
matrix now=fastm(pp,n-2);
ll num;
num=(b*now.mp[0][0])%MOD;
num=(num+a*now.mp[1][0]%MOD)%MOD;
num=(num+16*now.mp[2][0]%MOD)%MOD;
num=(num+8*now.mp[3][0]%MOD)%MOD;
num=(num+4*now.mp[4][0]%MOD)%MOD;
num=(num+2*now.mp[5][0]%MOD)%MOD;
num=(num+now.mp[6][0]%MOD)%MOD;
printf("%lld\n",num);
}
}
return 0;
}
越自律,越自由