hdu 1588 Gauss Fibonacci

/*
构造矩阵:
	   |1  1|      | f(2)    f(1)|
	A= |1  0|   =  | f(1)    f(0)|
		
		  
     |1  1| ^b   | f(b+1)    f(b)|			  
A^b =|1  0|  =   | f(b)    f(b-1)|
				
	f(b) = matrix[0][1]=matrix[1][0];
					  
	首项是:A^b
	公比是:A^k
	项数是:N
	可以把问题进一步简化
	因为矩阵的加法对乘法也符合分配律,我们提出一个A^b来,形成这样的式子:
	A^b*( I + A^k + (A^k)^2 + .... + (A^k)^(N-1) )
	A^b 和 A^k 显然都可以用我们之前说过的方法计算出来,这剩下一部分累加怎么解决呢
	设A^k=B
	要求 G(N)=I + ... + B^(N-1),
	i=N/2
	若N为偶数,G(N)=G(i)+G(i)*B^i = G(i) *( I+B^(i));
	若N为奇数,G(N)=I+ G(i)*B + G(i) * (B^(i+1)) = G(N-1)+B^N; (前一个等式可能要快点,但是后面更简练)
								  
	我们来设置这样一个矩阵
	B I
	O I
	其中O是零矩阵,I是单位矩阵
	将它乘方,得到
	B^2 I+B
	O   I
	乘三方,得到
	B^3 I+B+B^2
	O   I
	乘四方,得到
	B^4  I+B+B^2+B^3
	O    I								  
既然已经转换成矩阵的幂了,继续用我们的二分或者二进制法,直接求出幂就可以了
*/
#include <cstdio>
int M;
struct Matrix{
	__int64 e[2][2];
};
Matrix u,em;
Matrix Mul(Matrix a,Matrix b){
	Matrix c;
	for(int i=0;i<2;i++){
		for(int j=0;j<2;j++){
			c.e[i][j]=0;
			for(int k=0;k<2;k++){
				c.e[i][j]=(c.e[i][j]+a.e[i][k]*b.e[k][j])%M;
			}
		}
	}
	return c;
}
Matrix Add(Matrix a,Matrix b){
	for(int i=0;i<2;i++)
		for(int j=0;j<2;j++)
		a.e[i][j]=(a.e[i][j]+b.e[i][j])%M;
	return a;
}
Matrix Power(Matrix a,int n){
	Matrix t=u;
	for(;n;n>>=1,a=Mul(a,a))
		if(n&1)
			t=Mul(t,a);
	return t;
}
Matrix BinarySum(Matrix a,int n){
	if(n == 1) return a;
	return (n&1)?Add(BinarySum(a,n-1),Power(a,n)):Mul(BinarySum(a,n>>1),Add(Power(a,n>>1),u));

}
void Init(){
	u.e[0][0]=1,u.e[0][1]=0,u.e[1][0]=0,u.e[1][1]=1;
	em.e[0][0]=1,em.e[0][1]=1,em.e[1][0]=1,em.e[1][1]=0;
}
void Put(Matrix a){
	for(int i=0;i<2;i++)
		for(int j=0;j<2;j++)
			printf("%d\n",a.e[i][j]);
}
int main(){
	int k,b,n;
	Init();
	while(scanf("%d%d%d%d",&k,&b,&n,&M)!=EOF){
		Matrix t1,t2,ans;
		t1=Power(em,b);
		t2=Power(em,k);
		ans=Mul(Add(u,BinarySum(t2,n-1)),t1);
		printf("%d\n",ans.e[0][1]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值