K - 紀念SlingShot FZU - 1683-----------------------------------數論(矩陣快速冪)

在這裏插入圖片描述
在這裏插入圖片描述

解析:
Fn = [fnfn2fn3Sn]\begin{bmatrix}fn & fn-2 & fn-3 & Sn\end{bmatrix}
Fn+1 = [fn+1fnfn1Sn+1]\begin{bmatrix}fn+1 & fn & fn-1 & Sn+1\end{bmatrix}

因爲Sn+1 =Sn +Fn

[fnfn2fn3Sn]\begin{bmatrix}fn & fn-2 & fn-3 & Sn\end{bmatrix} * [3103201270070001]\begin{bmatrix}3 & 1& 0 & 3\\2 & 0 &1 & 2\\7 & 0 & 0 &7\\0 &0 & 0 & 1\end{bmatrix}

= [fn+1fnfn1Sn+1]\begin{bmatrix}fn+1 & fn & fn-1 & Sn+1\end{bmatrix}

最後等價於
[3279]\begin{bmatrix}3 &2& 7 & 9\end{bmatrix} * [3103201270070001]\begin{bmatrix}3 & 1& 0 & 3\\2 & 0 &1 & 2\\7 & 0 & 0 &7\\0 &0 & 0 & 1\end{bmatrix} (n-2) = [fn+1fnfn1Sn+1]\begin{bmatrix}fn+1 & fn & fn-1 & Sn+1\end{bmatrix}

#include<iostream>
#include<cstring>
using namespace std;
const int mod=2009;
struct lxw
{
	int res[4][4];
}node,base;
lxw multi(lxw a,lxw b)
{
	lxw tmp;
	memset(tmp.res,0,sizeof(tmp.res));
	for(int i=0;i<4;i++)
		for(int j=0;j<4;j++)
			for(int k=0;k<4;k++)
				tmp.res[i][j]+=(a.res[i][k]%mod*b.res[k][j]%mod)%mod;
		return tmp;
				
}
int main()
{
	int t;
	cin>>t;
	for(int i=0;i<t;i++)
	{
		int x;
		cin>>x;
		if(x==0)
		{
			printf("Case %d: 1\n",i+1);
			continue;
		} 	
		else if(x==1) 
		{
			printf("Case %d: 4\n",i+1);
			continue;
		}
		else if(x==2)
		{
			printf("Case %d: 9\n",i+1);
			continue;
		} 
		memset(node.res,0,sizeof(node.res));
		memset(base.res,0,sizeof(base.res));
		node.res[0][0]=5;node.res[0][1]=3;node.res[0][2]=1;node.res[0][3]=9;
		base.res[0][0]=3;base.res[0][1]=1;base.res[0][3]=3;
		base.res[1][2]=base.res[3][3]=1;
		base.res[1][0]=base.res[1][3]=2;
		base.res[2][0]=base.res[2][3]=7;
		int n=x-2;
		while(n)
		{
			if(n&1)
				node=multi(node,base);
			base=multi(base,base);
			n>>=1;
		}
		printf("Case %d: %d\n",i+1,(node.res[0][3]%mod));
	}
		return 0;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章