原题链接:
Given the value of a+b and ab you will have to find the value of an+bn. 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 00.
Output
For each test case, print the case number and (an+bn) modulo 264.
Sample Input
2
10 16 2
7 12 3
Sample Output
Case 1: 68
Case 2: 91
题意:
给出a+b的和p,ab的积q,要求计算出a^n+b^n的值。
题解:
利用递推公式:a^n+b^n=(a+b)(a^(n-1)+b^(n-1))-(ab)(a^(n-2)+b^(n-2))
建立矩阵关系:A=(p,1,-q,0)(2x2方阵)
(ans[n],ans[n-1])=A^(n-2)(ans[2],ans[1])
**注意:**由于A的指数为n-2,所以要对于n=0,1,2的三种情况进行特判。
由于题目要求mod2^64,所以数据类型必须是unsigned long long,至于mod2^64,这个好像没有必要。
附上AC代码:
#include
#include
#include
using namespace std;
#define LL unsigned long long
struct mat
{
LL a[2][2];
mat()
{
memset(a,0,sizeof(a));
}
mat operator * (mat b)
{
mat tmp;
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
for(int k=0;k<2;++k)
tmp.a[i][j]+=(a[i][k]*b.a[k][j]);
return tmp;
}
};
LL p,q,n;
mat quickpow(mat a,LL b)
{
mat res;
for(int i=0;i<2;++i)
res.a[i][i]=1;
while(b!=0)
{
if(b&1)
res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int main()
{
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
scanf("%llu%llu%llu",&p,&q,&n);
if(n==0)
{
printf("Case %d: 2\n",cas);
continue;
}
if(n==1)
{
printf("Case %d: %llu\n",cas,p);
continue;
}
if(n==2)
{
printf("Case %d: %llu\n",cas,p*p-2*q);
continue;
}
mat A,ans;
ans.a[0][1]=p,ans.a[0][0]=(p*p-2*q);
A.a[0][0]=p,A.a[0][1]=1,A.a[1][0]=-q;
A=quickpow(A,n-2);
ans=ans*A;
printf("Case %d: %llu\n",cas,ans.a[0][0]);
}
return 0;
}
欢迎评论!