Given the value of a+b and ab you will have to find the value of a^n+b^n. a and b not necessarily have to be real numbers.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case contains three non-negative integers, p, q and n. Here p denotes the value of a+b and q denotes the value of ab. Each number in the input file fits in a signed 32-bit integer. There will be no such input so that you have to find the value of 0^0.
Output
For each test case, print the case number and (a^n+b^n) modulo 2^64.
Sample Input
2
10 16 2
7 12 3
Sample Output
Case 1: 68
Case 2: 91
思路:假设f(n)=a^n+b^n,那么可推得f(n)=f(n-1)*(a+b)-f(n-2)*a*b,然后用矩阵快速幂来搞即可。
注意:模2^64,定义成unsigned long long 类型,因为无符号类型超过最大范围的数与该数%最大范围 的效果是一样的
代码如下
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define LL long long
#define ULL unsigned long long
//const int mod=7;
struct matrix
{
ULL x[2][2];
};
matrix mutimatrix(matrix a,matrix b)
{
matrix temp;
memset(temp.x,0,sizeof(temp.x));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
{
temp.x[i][j]+=a.x[i][k]*b.x[k][j];
//temp.x[i][j]%=mod;
}
return temp;
}
matrix k_powmatrix(matrix a,LL n)
{
matrix temp;
memset(temp.x,0,sizeof(temp.x));
for(int i=0;i<2;i++)
temp.x[i][i]=1;
while(n)
{
if(n&1)
temp=mutimatrix(temp,a);
a=mutimatrix(a,a);
n>>=1;
}
return temp;
}
int main()
{
int T;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++)
{
ULL q,p,n;
scanf("%llu %llu %llu",&p,&q,&n);
if(n==0)
{
printf("Case %d: %llu\n",cas,2);
continue;
}
if(n==1)
{
printf("Case %d: %llu\n",cas,p);
continue;
}
matrix st;
memset(st.x,0,sizeof(st.x));
st.x[0][0]=p;
st.x[0][1]=1;
st.x[1][0]=-q;
st.x[1][1]=0;
matrix init;
memset(init.x,0,sizeof(init.x));
init.x[0][0]=p;
init.x[0][1]=2;
st=k_powmatrix(st,n-1);
st=mutimatrix(init,st);
printf("Case %d: %llu\n",cas,st.x[0][0]);
}
return 0;
}