hdu 1005 簡單題

今早水出的第一道題,帶着情緒做的,竟然1Y了,確實驚奇。這道簡單的線性遞推取模,直接遞推是不行的,因爲n的規模達到了100,000,000,要麼超時要麼超內存。可以用矩陣快速冪來搞,根據題意構建出對應的矩陣後即可(第一次寫的,用結構體來進行矩陣相乘運算),代碼如下:

<span style="font-size:18px;">#include<cstdio>

struct matrix{
	int a,b,c,d;
	matrix(int _a=1, int _b=0, int _c=1, int _d=0) {
		a=_a;	b=_b;	c=_c;	d=_d;
	}
	matrix operator *(const matrix &m2){
		return matrix((a*m2.a%7+b*m2.c%7)%7, (a*m2.b%7+b*m2.d%7)%7, (c*m2.a%7+d*m2.c%7)%7, (c*m2.b%7+d*m2.d%7)%7);
	}
	matrix square(){
		return matrix((a*a%7+b*c%7)%7, b*(a+d)%7, c*(a+d)%7, (b*c%7+d*d%7)%7);
	}
};

int calcu(matrix m, int p)
{
	matrix ans(1,0,0,1);
	while(p){
		if(p&1)	ans= ans*m;
		m= m.square();
		p>>=1;
	}
	return (ans.a+ans.c)%7;
}

int main()
{
	int a,b,n;
	while(scanf("%d%d%d",&a,&b,&n),a){
		if(n<=2)	puts("1");
		else	printf("%d\n", calcu(matrix(a,1,b,0),n-2));
	}
	return 0;
}</span>


實際上,這道題還有更優的做法,就是找循環週期,因爲f[n]只與前兩個有關,而且是模7,所以它的循環週期是7*7-1=48(爲何這樣算我也不知如何證明,留待以後再想),下面也附上AC代碼:

<span style="font-size:18px;">#include<cstdio>
int f[49]= {0,1,1};

int main()
{
	int a,b,n,i;
	while(scanf("%d%d%d",&a,&b,&n), a){
		for(i=3; i<=48; ++i)
			f[i]= (a*f[i-1]+b*f[i-2])%7;
		f[0]= f[48];
		printf("%d\n",f[n%48]);
	}
	return 0;
}</span>



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章