习题:Recursive sequence(矩阵加速)

题目

传送门

思路

\(s_1=a\)

\(s_2=b\)

\(s_i=2*s_{i-1}+s_{i-2}+i^4\)

\((i+1)^4=i^4+4*i^3+8*i^2+4*i+1\)

\((i+1)^3=i^3+3*i^2+3*i+1\)

\(init=\begin{bmatrix}s_{i-1}\\s_{i-2}\\i^4\\i^3\\i^2\\i\\1\end{bmatrix}\)

\(acc=\begin{bmatrix}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,1,1\\0,0,0,0,0,0,1\end{bmatrix}\)

代码

#include<iostream>
#include<cstring>
using namespace std;
long long n,t;
long long a,b;
const long long mod=2147493647;
struct node
{
	long long n,m;
	long long a[15][15];
	node operator * (const node &b)
	{
		node c;
		c.n=n;
		c.m=b.m;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=b.m;j++)
			{
				c.a[i][j]=0;
				for(int k=1;k<=m;k++)
				{
					c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
				}
			}
		}
		return c;
	}
};
node qkpow(node a,long long b)
{
	if(b==1)
		return a;
	node t=qkpow(a,b/2);
	t=t*t;
	if(b%2==1)
		t=t*a;
	return t;
}
node init,acc;
void c_in()
{
	cin>>n>>a>>b;
	memset(init.a,0,sizeof(init.a));
	memset(acc.a,0,sizeof(acc.a));
	if(n==1)
	{
		cout<<a<<'\n';
		return;
	}
	if(n==2)
	{
		cout<<b<<'\n';
		return;
	}
	init.n=4;
	init.m=1;
	init.a[1][1]=b;
	init.a[2][1]=a;
	init.a[3][1]=3*3*3*3;
	init.a[4][1]=3*3*3;
	init.a[5][1]=3*3;
	init.a[6][1]=3;
	init.a[7][1]=1;
	acc.n=7;
	acc.m=7;
	acc.a[1][2]=acc.a[5][6]=2;
	acc.a[1][1]=acc.a[1][3]=acc.a[2][1]=acc.a[3][3]=acc.a[3][7]=acc.a[4][4]=acc.a[4][7]=acc.a[5][5]=acc.a[5][7]=acc.a[6][6]=acc.a[6][7]=acc.a[7][7]=1;
	acc.a[3][4]=acc.a[3][6]=4;
	acc.a[3][5]=6;
	acc.a[4][5]=acc.a[4][6]=3;
	init=qkpow(acc,n-2)*init;
	cout<<init.a[1][1]<<'\n';
}
int main()
{
	cin>>t;
	for(int i=1;i<=t;i++)
		c_in();
	return 0;
}
posted @ 2019-12-30 21:20  loney_s  阅读(197)  评论(0)    收藏  举报