HZAU 1202 GCD (矩阵快速幂 + GCD)

来源:互联网 发布:获取所有股票信息 js 编辑:程序博客网 时间:2024/04/29 19:54

Problem Description

Xiao Ming found the compute time of gcd(fibn,fibn+1) is the most when he learnt the gcd, and the result of it is always fib1 but he is not satisfied with the simple compute result.

He wants to know what gcd(1+Sn,1+Sm) equals.

And gcd is greatest common divisor,

fib1=1,fib2=1,fibn=fibn1+fibn2(n3)

Sn=i=1nfibi


Input Description

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 Description

In each test case, output the compute result of gcd(1+Sn,1+Sm)%p at one line.


Sample Input:

11 2 3


Sample Output:

1


题意

给出 n,m,p 三个整数,求斐波那契数列前 n 项和与前 m 项和的最大公约数模 p


思路

斐波那契数列有这样两条性质:

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

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


于是,题目的答案便是 Fgcd(n,m)%p 咯!

最大公约数可以用辗转相除法求得,然后再利用矩阵快速幂得到斐波那契数第 k 项,记得模 p 哦~


AC 代码

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>using namespace std;typedef long long LL;LL n,m,mod;LL gcd(LL a,LL b){    if(b==0)return a;    return gcd(b,a%b);}struct node{    LL mp[2][2];    void init(LL a,LL b,LL c,LL d)    {        mp[0][0]=a;        mp[0][1]=b;        mp[1][0]=c;        mp[1][1]=d;    }    void mult(node x,node y)                //两矩阵乘法    {        memset(mp,0,sizeof(mp));        for(LL i=0; i<2; i++)            for(LL j=0; j<2; j++)                for(LL k=0; k<2; k++)                    mp[i][j]=(mp[i][j]+x.mp[i][k]*y.mp[k][j])%mod;    };} init;struct node expo(struct node x, LL k)  //进行k次幂运算{    struct node tmp;    tmp.init(1,0,0,1);                      //单位矩阵    while(k)                                //快速幂部分    {        if(k&1)tmp.mult(tmp,x);        x.mult(x,x);        k>>=1;    }    return tmp;}int main(){    int T;    ios::sync_with_stdio(false);    cin>>T;    while(T--)    {        cin>>n>>m>>mod;        int k=gcd(n+2,m+2);        init.init(1,1,1,0);        cout<<expo(init,k).mp[0][1]%mod<<endl;    }    return 0;}
0 0