HDU 1588 Gauss Fibonacci

http://acm.hdu.edu.cn/showproblem.php?pid=1588

已知:

g(i)=ki+b

f(0)=0 , f(1)=1 ,f[n]=f[n-1]+f[n-2]

求解:

因为斐波那契存在关系:

有:


所以:

换元表示:


接下来处理,矩阵快速幂和等比数列。

关于等比数列:


即递归处理。

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL k,b,n,M;
struct matrix{
	LL m[2][2];
};
matrix A={
1,1,
1,0
};
matrix I={
1,0,
0,1
};
matrix multi(matrix a,matrix b){
	matrix ans;
	for(int i=0;i<2;i++){
		for(int j=0;j<2;j++){
			ans.m[i][j]=0;
			for(int k=0;k<2;k++){
				ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j]%M)%M;
			}
		}
	}
	return ans;
}
matrix quick(matrix a,int n){
    matrix ans=I,temp=a;
    if(n==-1){
        ans.m[0][0]=0;   ans.m[0][1]=1;
        ans.m[1][0]=1;   ans.m[1][1]=-1;
        return ans;
    }
    while(n>0){
    	if(n&1) ans=multi(ans,temp);
    	temp=multi(temp,temp);
    	n>>=1;
    }
    return ans;
}
matrix add(matrix a,matrix b){
    matrix ans;
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            ans.m[i][j]=(a.m[i][j]+b.m[i][j])%M;
        }
    }
    return ans;
}
matrix selfquick(matrix t,int n){
    if(n==0) return I;

    if(n&1){
        matrix mid=quick(t,n/2+1);
        return multi(add(mid,I),selfquick(t,n/2)); //尽量少用递归
    }
    else {
        matrix mid=quick(t,n/2);
        matrix miadd=quick(t,n/2+1);
        matrix q1=multi(add(miadd,I),selfquick(t,n/2-1));
        return add(q1,quick(t,n/2));
    }
}

int main(int argc, char *argv[]) {
    while(~scanf("%lld%lld%lld%lld",&k,&b,&n,&M)){
    	matrix t1=quick(A,b-1),t2=quick(A,k);
        t2=selfquick(t2,n-1);
        matrix ans=multi(t1,t2);
        printf("%lld\n",ans.m[0][0]);
    }
	return 0;
}


你可能感兴趣的:(fibonacci)