题链:http://lightoj.com/volume_showproblem.php?problem=1070
1070 - Algebraic Problem
|
PDF (English) |
Statistics |
Forum |
Time Limit: 2 second(s) |
Memory Limit: 32 MB |
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
|
Output for Sample Input
|
2
10 16 2
7 12 3
|
Case 1: 68
Case 2: 91
|
题意:
给你p=a+b, q=ab
算出 (a^n+b^)mod2^64
做法:
mod 2^64所以开 unsigned long long ,llu 就行了,达到上限会自动取模的。
然后就是公式了。我是在推公式中找到的规律。
a^2+b^2=(a+b)*(a+b)-2*a*b
a^3+b^3=(a^2+b^2)*(a+b)-a*b(a+b)
a^4+b^4=(a^3+b^3)*(a+b)-a*b(a^2+b^2)
设G(n)=a^n+b^n
G(n)=G(n-1)*p-G(G-2)*q
然后就是快速幂了。.
#include
#include
#define Matr 5 //矩阵大小,注意能小就小 矩阵从1开始 所以Matr 要+1 最大可以100
#define ll unsigned long long
struct mat//矩阵结构体,a表示内容,size大小 矩阵从1开始 但size不用加一
{
ll a[Matr][Matr];
mat()//构造函数
{
memset(a,0,sizeof(a));
}
};
int Size= 2;
mat multi(mat m1,mat m2)//两个相等矩阵的乘法,对于稀疏矩阵,有0处不用运算的优化
{
mat ans=mat();
for(int i=1;i<=Size;i++)
for(int j=1;j<=Size;j++)
if(m1.a[i][j])//稀疏矩阵优化
for(int k=1;k<=Size;k++)
ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k]); //i行k列第j项
return ans;
}
mat quickmulti(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;
}
void print(mat m)//输出矩阵信息,debug用
{
int i,j;
printf("%d\n",Size);
for(i=1;i<=Size;i++)
{
for(j=1;j<=Size;j++)
printf("%llu ",m.a[i][j]);
printf("\n");
}
}
int main()
{
/*
ll a,b;
while(scanf("%llu",&a)!=EOF)
printf("%llu\n",-a+18446744073709551615+1);
*/
int t;
int cas=1;
scanf("%d",&t);
while(t--)
{
ll p,q,n;
int p1,q1;
scanf("%lld%lld%llu",&p,&q,&n);// p a+b q ab
ll tem=18446744073709551615-q+1;
mat gouzao=mat(),chu=mat();//构造矩阵 初始矩阵
chu.a[1][1]=p;
chu.a[1][2]=p*p+2*tem;
chu.a[1][3]=q;
printf("Case %d: ",cas++);
if(n==0)
printf("2\n");
else if(n==1)
printf("%llu\n",p);
else if(n==2)
printf("%llu\n",p*p+2*tem);
else
{
gouzao.a[1][1]=0;
gouzao.a[2][1]=1;
gouzao.a[1][2]=tem;
gouzao.a[2][2]=p;
//print(gouzao);
printf("%llu\n",multi(chu,quickmulti(gouzao,n-2)).a[1][2]);
}
}
return 0;
}
/*
ans^=n -
mat ans=mat();
ans.size=Size;
初始化ans矩阵
ans=quickmulti(ans,n,mod);
void print(mat m)//输出矩阵信息,debug用
{
int i,j;
printf(%dn,m.size);
for(i=1;i=m.size;i++)
{
for(j=1;j=m.size;j++)printf(%d ,m.a[i][j]);
printf(n);
}
}
*/
版权声明:本文为博主原创文章,未经博主允许不得转载。
LightOJ 1070 - Algebraic Problem 矩阵快速幂