HDU - 2842

要拆第n个环要求保留第n-1拆除前n-2
对于n,先拆掉n-2再去掉n再放回n-2,然后规模降为n-1
f(n)=2f(n-2)+f(n-1)+1

inline ll mod(ll a){return a%MOD;}
struct Matrix{
	ll mt[5][5],r,c;
	void init(int rr,int cc,bool flag=0){
		r=rr;c=cc;
		memset(mt,0,sizeof mt);
		if(flag) rep(i,1,r) mt[i][i]=1;
	}
	Matrix operator * (const Matrix &rhs)const{
		Matrix ans; ans.init(r,rhs.c);
		rep(i,1,r){
			rep(j,1,rhs.c){
				int t=max(r,rhs.c);
				rep(k,1,t){
					ans.mt[i][j]+=mod(mt[i][k]*rhs.mt[k][j]);
					ans.mt[i][j]=mod(ans.mt[i][j]);
				}
			}
		}
		return ans;
	}
};
Matrix fpw(Matrix A,ll n){
	Matrix ans;ans.init(A.r,A.c,1);
	while(n){
		if(n&1) ans=ans*A;
		n>>=1;
		A=A*A;
	}
	return ans;
}

int bas[4][4]={
	{0,0,0,0},
	{0,1,2,1},
	{0,1,0,0},
	{0,0,0,1}
};
int bas2[4]={0,2,1,1}; 
ll n;
int main(){
	Matrix A;A.init(3,3);
	rep(i,1,3) rep(j,1,3) A.mt[i][j]=bas[i][j];
	Matrix b; b.init(3,1);
	rep(i,1,3) b.mt[i][1]=bas2[i];
	while(cin>>n){
		if(n==0)break;
		if(n<=2){
			if(n==1) println(1);
			if(n==2) println(2);
			continue;
		}
		Matrix res=fpw(A,n-2); res=res*b;
		ll ans=mod(res.mt[1][1]);
		println(ans);
	}
	return 0;
}
posted @ 2018-02-15 17:12  Caturra  阅读(148)  评论(0编辑  收藏  举报