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

这里写图片描述
这里写图片描述

/*
矩阵乘法+快速幂.
一开始迷之题意.. 
这个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;
}
posted @ 2016-10-06 21:33  nancheng58  阅读(101)  评论(0编辑  收藏  举报