题目大意:给定a+b,和a*b和n,问a^n+b^n;
题目解析:因为a^n+b^n=(a^(n-1) + b^(n-1))*(a + b) - (a^(n-2) + b^(n-2))*(a*b);
所以就可以得出递推式,令f(n)=(a+b)*f(n-1)-a*b*f(n-2);
初始矩阵[a+b,a^2+b^2],递推矩阵[0 -a*b]
[1 a+b];
最后的答案是结果矩阵的[1,2];
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#define ll unsigned long long
using namespace std;
const int size=2;
struct mat
{
ll a[5][5];
mat()
{
memset(a,0,sizeof(a));
}
};
mat multi(mat m1,mat m2)
{
int i,j,k;
mat ans=mat();
for(i=1;i<=2;i++)
for(j=1;j<=2;j++)
if(m1.a[i][j])
for(k=1;k<=2;k++)
ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k]);
return ans;
}
mat fun(mat m,ll n)
{
mat ans=mat();
int i;
for(i=1;i<=size;i++)ans.a[i][i]=1;
while(n)
{
if(n&1)ans=multi(m,ans);
m=multi(m,m);
n>>=1;
}
return ans;
}
int main()
{
int cas,c,i;
ll p,q,n;
scanf("%d",&cas);
for(c=1;c<=cas;c++)
{
scanf("%lld%lld%llu",&p,&q,&n);
ll m=18446744073709551616-q;
mat chu=mat(),gouzao=mat();
chu.a[1][1]=p;
chu.a[1][2]=p*p+2*m;
printf("Case %d: ",c);
if(n==0)
printf("2\n");
else if(n==1)
printf("%llu\n",p);
else if(n==2)
printf("%llu\n",p*p+2*m);
else
{
gouzao.a[1][1]=0;
gouzao.a[1][2]=m;
gouzao.a[2][1]=1;
gouzao.a[2][2]=p;
printf("%llu\n",multi(chu,fun(gouzao,n-2)).a[1][2]);
}
}
return 0;
}