Sweety

Practice makes perfect

导航

HZAU 1202 GCD( 斐波那契数列+矩阵快速幂)

Posted on 2017-04-24 21:47  蓝空  阅读(297)  评论(0编辑  收藏  举报

Problem D: GCD

Time Limit: 1 Sec  Memory Limit: 1280 MB
Submit: 194  Solved: 27
[Submit][Status][Web Board]

Description


Input

 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.

Output


Sample Input

1 
1 2 3

Sample Output

1

HINT




题意简单!!!




斐波那契数列本身性质:

gcd(Fn,Fm)=Fgcd(n,m)

F1+F2+F3+F4+F5+...+Fn+1=Fn+2



关于斐波那契数列矩阵快速幂基础知识:加法转矩阵快速幂(here

由通式可得,斐波那契数列是个二阶递推数列,因此,存一个二维矩阵A,使得

Fn+3 =(Fn+2,Fn+1)=(Fn+1,Fn)*A;

有规律可得,A=  1 1

                               1 0

Fn+4=(Fn+3,Fn+2)=(Fn+1,Fn)*A*A =)=(Fn+1,Fn)*A^2;



#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define eps 1e-4
const int N=1e6+10,M=1e6+10;

///数组大小
ll MOD;

struct Matrix
{
    ll matri[2][2];
    Matrix()
    {
        memset(matri,0,sizeof(matri));
    }
    void init()
    {
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                matri[i][j]=(i==j);
    }
    Matrix operator + (const Matrix &B)const
    {
        Matrix C;
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                C.matri[i][j]=(matri[i][j]+B.matri[i][j])%MOD;
        return C;
    }
    Matrix operator * (const Matrix &B)const
    {
        Matrix C;
        for(int i=0;i<2;i++)
            for(int k=0;k<2;k++)
                for(int j=0;j<2;j++)
                    C.matri[i][j]=(C.matri[i][j]+1LL*matri[i][k]*B.matri[k][j])%MOD;
        return C;
    }
    Matrix operator ^ (const ll &t)const
    {
        Matrix A=(*this),res;
        res.init();
        ll p=t;
        while(p)
        {
            if(p&1)res=res*A;
            A=A*A;
            p>>=1;
        }
        return res;
    }
};
int main()
{
    Matrix base;  ///初始化矩阵
    base.matri[0][0]=1;base.matri[0][1]=1;
    base.matri[1][0]=1;base.matri[1][1]=0;

    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m,p;
        scanf("%d%d%d",&n,&m,&p);
        int x=__gcd(n+2,m+2);
        MOD=p;
        if(x<=2)
            printf("%d\n",1%p);
        else
        {
            Matrix ans=base^(x-2);
            printf("%lld\n",(ans.matri[0][0]+ans.matri[0][1])%MOD);
        }
    }
    return 0;
}