HDU 5950:Recursive sequence

HDU 5950:Recursive sequence

题目大意

f n = f n − 1 + 2 × f i − 2 + n 4 f_n=f_{n-1}+2\times f_{i-2}+n^4 fn=fn1+2×fi2+n4,其中 f 1 = a , f 2 = b f_1=a,f_2=b f1=a,f2=b

思路

如果没有 n 4 n^4 n4,那就是一个异常简单的noip普及组难度,但是现在有了,那怎么办呢?我们考虑 ( n + 1 ) 4 = n 4 + 4 × n 3 + 6 × n 2 + 4 × n + 1 (n+1)^4=n^4+4\times n^3+6\times n^2+4\times n+1 (n+1)4=n4+4×n3+6×n2+4×n+1,所以,如果我们把 n 4 n^4 n4也加入初始矩阵,那我们 n 3 , n 2 , n , 1 n^3,n^2,n,1 n3,n2,n,1都加进初始矩阵,而 ( n + 1 ) 3 = n 3 + 3 × n 2 + 3 × n + 1 , ( n + 1 ) 2 = n 2 + 2 × n + 1 , ( n + 1 ) = n + 1 (n+1)^3=n^3+3\times n^2+3\times n+1,(n+1)^2=n^2+2\times n+1,(n+1)=n+1 (n+1)3=n3+3×n2+3×n+1,(n+1)2=n2+2×n+1,(n+1)=n+1,然后,我们就可以构造出初始矩阵和转移矩阵了,大概长成这样:
( f 2 f 1 3 4 3 3 3 2 3 1 3 0 ) \begin{pmatrix} f_2\\ f_1\\ 3^4\\ 3^3\\ 3^2\\ 3^1\\ 3^0 \end{pmatrix} f2f13433323130
                                                                          × \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \times                                                                          ×
( 1 2 1 0 0 0 0 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 0 1 ) \begin{pmatrix} 1&2&1&0&0&0&0\\ 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&0&1 \end{pmatrix} 110000200000101000004100006310004320001111
我觉得,当 n = 1 o r 2 n=1or2 n=1or2的时候需要特判一下,然后顺便开一下long long,但是我错了很多次,主要就是转移矩阵一个笔误码误,废了我的一生,但是样例太弱了,诶~,太菜了

代码

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

#define Int register int
#define int long long
#define MAXN 10

int mod = 2147493647ll;

struct Matrix
{
	int n,m;
	int a[MAXN][MAXN];
	Matrix(){memset (a,0,sizeof (a));}
	Matrix operator * (const Matrix &p)const
	{
		Matrix New;
		New.n = n,New.m = p.m;
		for (Int i = 1;i <= New.n;++ i)
			for (Int j = 1;j <= New.m;++ j)
				for (Int k = 1;k <= m;++ k)
					New.a[i][j] = (New.a[i][j] + a[i][k] % mod * p.a[k][j] % mod) % mod;
		return New;
	}
};

Matrix quick_pow (Matrix a,int b)
{
	Matrix res;
	res.n = res.m = a.n;
	for (Int i = 1;i <= res.n;++ i) res.a[i][i] = 1;
	while (b)
	{
		if (b & 1)
			res = res * a;
		a = a * a;
		b >>= 1;
	}
	return res;
}

void read (int &x)
{
	x = 0;char c = getchar ();int f = 1;
	while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}
	while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + c - '0';c = getchar();}
	x *= f;return ;
}

void write (int x)
{
	if (x < 0){x = -x;putchar ('-');}
	if (x > 9) write (x / 10);
	putchar (x % 10 + '0');
}

signed main()
{
	Matrix A,B,C;		
	B.n = B.m = 7;
	B.a[1][1] = 1,B.a[1][2] = 2,B.a[1][3] = 1;
	B.a[2][1] = 1;
	B.a[3][3] = 1,B.a[3][4] = 4,B.a[3][5] = 6,B.a[3][6] = 4,B.a[3][7] = 1;
	B.a[4][4] = 1,B.a[4][5] = 3,B.a[4][6] = 3,B.a[4][7] = 1;
	B.a[5][5] = 1,B.a[5][6] = 2,B.a[5][7] = 1;
	B.a[6][6] = 1,B.a[6][7] = 1;
	B.a[7][7] = 1;
	int times;
	read (times);
	while (times --)
	{
		int N,a,b;
		read (N),read (a),read (b);
		a %= mod,b %= mod;
		if (N == 1)
		{
			write (a),putchar ('\n');
			continue;
		}
		else if (N == 2)
		{
			write (b),putchar ('\n');
			continue;
		}
		A.n = 7,A.m = 1;
		A.a[1][1] = b,A.a[2][1] = a,A.a[3][1] = 81,A.a[4][1] = 27,A.a[5][1] = 9,A.a[6][1] = 3,A.a[7][1] = 1;
		C = quick_pow (B,N - 2) * A;
		write (C.a[1][1]),putchar ('\n');
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值