问题 : GCD
时间限制: 1 Sec 内存限制: 1280 MB提交: 18 解决: 7
[ 提交][ 状态]
题目描述
输入
The first line is an positive integer T . (1<=T<= 10^3) indicates the number of test cases. In the next T lines, there are three positive integer n, m, p (1<= n,m,p<=10^9) at each line.
输出
样例输入
1
1 2 3
样例输出
1
题目大意:给出一个公式,现在要求求出公式的最后结果。
解题思路: 题目上可以看到数据范围很大,用普通方法肯定不行,对于这种情况应该只有两种情况,一种是式子结果在数据范围内很少,那么这时间可以直接打表,如果特别多,那么就表示这种题有某种规律,可以先试着写出普通的代码,输出一些数据查找规律。这一题正好是后一种情况,对于盖提而言式子的结果是求出第m,n最大公约数加上二个斐波那契额数字。当然这样来说数据范围同样很大,因此应该鞥想到矩阵快速幂来求解。
快速幂还是很好理解的,对于a^b
当b为偶数时可以转化为a^2的b/2
当b为奇数时可以转化为a^2的b/2次方乘以a
而对于矩阵快数幂又涉及到了矩阵相乘,再加上快速幂来迅速解决问题。
对于矩阵乘法求斐波那契额数可以搜索资料了解, 就不在多说了
代码:
#include<stdio.h>
#include<string.h>
#define N 10long long p;
typedef struct stu{
long long a[4][4];
}st;
st fun(st u,st v)
{
long long i,j,k;
long long c[N][N]={0};
for(i=1;i<=2;i++)
for(j=1;j<=2;j++)
for(k=1;k<=2;k++)
{
c[i][j]=(c[i][j]+u.a[i][k]*v.a[k][j])%p;
}
for(i=1;i<=2;i++)
for(j=1;j<=2;j++)
u.a[i][j]=c[i][j];
return u;
}
st pow(long long n)
{
st u,v;
u.a[1][1]=u.a[1][2]=u.a[2][1]=1;
v.a[1][1]=1;v.a[2][2]=1;
u.a[2][2]=v.a[1][2]=v.a[2][1]=0;
while(n)
{
if(n&1)
v=fun(u,v);
u=fun(u,u);
n=n>>1;
}
return v;
}
long long fun1(long long a,long long b)
{
if(!b)
return a;
else
return fun1(b,a%b);
}
int main()
{
long long i,j,k,m,n,x,y,t;
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld%lld",&m,&n,&p);
st w,z,u1,v1;
m+=2;n+=2;
m=fun1(m,n);
u1=pow(m);
x=u1.a[1][2];
printf("%lld\n",x%p);
}
return 0;
}
本人菜鸟一个,如若文章能给你有所启发不胜荣幸。如有不足之处还望指出,非常感谢!