UVA - 10655 Contemplation! Algebra

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lidengdengter/article/details/81623444

题目链接

给定a+b,a*b和n,要求a^{n}+b^{n}的值。

要通过a+b和a*b求a和b,再求n次方和,显然不是很容易,我们进行转换:

f(n)=a^{n}+b^{n}=(a+b)(a^{n-1}+b^{n-1})-ba^{n-1}-ab^{n-1}

f(n)=(a+b)(a^{n-1}+b^{n-1})-ab(a^{n-2}+b^{n-2})

f(n)=(a+b)f(n-1)-abf(n-2)=pf(n-1)-qf(n-2)

即转换成递推式,再利用矩阵快速幂求解即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
struct matrix{
	ll x[3][3];
};
matrix ans;

matrix multi(matrix a,matrix b){
	matrix tmp;
	memset(tmp.x,0,sizeof(tmp.x));
	for(int i=1;i<=2;i++)
		for(int j=1;j<=2;j++)
			for(int k=1;k<=2;k++){
				tmp.x[i][j]=tmp.x[i][j]+a.x[i][k]*b.x[k][j];
			}
				
	return tmp;
}

matrix quick_multi(matrix a,int n){
	matrix t;
	for(int i=1;i<=2;i++)
		for(int j=1;j<=2;j++)
			t.x[i][j]=(i==j);
			
	while(n){
		if(n&1)
			t=multi(t,a);
		a=multi(a,a);
		n>>=1;
	}
	return t;
}
int main()
{
	ll p,q,n;
	while(scanf("%lld%lld%lld",&p,&q,&n)==3){
		if(n==0){
			printf("2\n");
			continue;
		} 
		if(n==1){
			printf("%lld\n",p);
			continue;
		}
//		if(n==2){
//			printf("lld\n",p*p-2*q);
//			continue;
//		}
		matrix A;
		matrix ans;
		memset(A.x,0,sizeof(A.x));
		memset(ans.x,0,sizeof(ans.x));
		A.x[1][1]=p;A.x[2][1]=-q;
		A.x[1][2]=1;A.x[2][2]=0;
		
		ans.x[1][1]=p;ans.x[1][2]=2;
		
		A=quick_multi(A,n-1);
		ans=multi(ans,A);
		printf("%lld\n",ans.x[1][1]);
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/lidengdengter/article/details/81623444