HDU 5667 Sequence(矩阵快速幂+费马小定理)

来源:互联网 发布:mac 虚拟机 游戏 编辑:程序博客网 时间:2024/05/16 19:55

大意:

这里写图片描述

He gives you 5 numbers n,a,b,c,p,and he will eat fn foods.But there are only p foods,so you should tell him fn mod p.

Input
The first line has a number,T,means testcase.

Each testcase has 5 numbers,including n,a,b,c,p in a line.1≤T≤10,1≤n≤1018,1≤a,b,c≤109,p is a prime number,and p≤109+7.

思路:矩阵快速幂一定可以,那么a的指数很大怎么处理呢那么用费马小定理a^(p-1)%p=1;a^(m%(p-1)) %p=1 ; 最后注意 a%p==0的情况。

//|G(n)  |  |c 1 b|  |G(n-1)|  //|G(n-1)|= |1 0 0|* |G(n-2)|  //|1     |  |0 0 1|  |1     |  #include<map>#include<queue>#include<cmath>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define LL int#define inf 0x3f3f3f3f#define eps 1e-8#include<vector>#define ls l,mid,rt<<1#define rs mid+1,r,rt<<1|1using namespace std;__int64 mod ,p;struct node{    __int64 r[15][15];}q;void matrix_pow(node &a,node &b){    int i,j,k;    node t;    for(i= 0;i <3;++ i){        for(j = 0;j < 3;++ j){            t.r[i][j]  = 0;        }    }    for(k = 0;k < 3;++ k){        for(i =0 ;i < 3;i++){            for(j = 0;j < 3;++ j){                t.r[i][j] = (t.r[i][j]+a.r[i][k]*b.r[k][j])%mod;            }        }    }    a = t;}void so(node &q,__int64 m){    __int64 i,j,k;    node tmp;    for(i= 0;i <3;++ i){        for(j = 0;j < 3;++ j){            tmp.r[i][j]  = 0;        }    }    for(i=0;i<3;++i)        tmp.r[i][i]=1;    while(m){        if(m&1){           matrix_pow(tmp,q);        }        matrix_pow(q,q);        m =m >> 1;    }   q = tmp;}__int64 qick(__int64 x,__int64 y){    x = x%p;    __int64 ba  = x,r = 1;    while(y){        if(y&1)            r = (r*ba) % p;        ba  = (ba * ba) % p;        y >>= 1;    }    return r;}int main(){    __int64 k,i,j,n,a,b,c;    int cla;    scanf("%d",&cla);    while(cla--){        scanf("%I64d %I64d %I64d %I64d %I64d",&n,&a,&b,&c,&p);        if(n == 1){            printf("1\n");continue;        }        else if(n==2){            printf("%I64d\n",qick(a,b));continue;        }        else if(a%p==0){            puts("0");continue;        }        mod = p - 1;        memset(q.r,0,sizeof(q.r));        q.r[0][0] = c,q.r[0][2]=b;        q.r[0][1] = q.r[1][0] = q.r[2][2] = 1;        so(q,n-2);        __int64 ans  =0;        ans = (ans + b*q.r[0][0])%mod;        ans = (ans + q.r[0][2])%mod;        printf("%I64d\n",qick(a,ans));    }    return 0;}
0 0
原创粉丝点击