您的位置:首页 > 其它

Qbxt 模拟赛 Day4 T2 gcd(矩阵乘法快速幂)

2016-10-06 21:33 344 查看




/*
矩阵乘法+快速幂.
一开始迷之题意..
这个gcd有个规律.
a b
b c=a*x+b(x为常数).
然后要使b+c最小的话.
那x就等于1咯.
那么问题转化为求
a b
b a+b
就是斐波那契了....
*/
#include<iostream>
#include<cstdio>
#define MAXN 3
#define LL long long
#define mod 1000000007
using namespace std;
LL n;
LL a[MAXN][MAXN],ans[MAXN][MAXN],c[MAXN][MAXN],b[MAXN][MAXN];
LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void mi(LL n)
{
while(n)
{
if(n&1)
{
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
c[i][j]=(c[i][j]+ans[i][k]*b[k][j]%mod)%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
ans[i][j]=c[i][j],c[i][j]=0;
}
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
c[i][j]=(c[i][j]+b[i][k]*b[k][j]%mod)%mod;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
b[i][j]=c[i][j],c[i][j]=0;
n>>=1;
}
}
void slove()
{
b[1][2]=ans[1][2]=1,b[2][1]=ans[2][1]=1;
b[1][1]=ans[1][1]=0;
b[2][2]=ans[2][2]=1;
mi(n);
ans[1][2]%=mod,ans[2][2]%=mod;
printf("%d ",min(ans[1][2],ans[2][2]));
printf("%d",max(ans[1][2],ans[2][2]));
}
int main()
{
freopen("gcd.in","r",stdin);
freopen("gcd.out","w",stdout);
n=read();
if(n==1) printf("1 1\n");
else slove();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: