HDU5667——费马小定理

Posted mingusu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU5667——费马小定理相关的知识,希望对你有一定的参考价值。

题目链接

------------恢复内容开始------------

题目链接:https://vjudge.net/problem/HDU-5667

题目意思:按照递推式求出第n项对p求余的结果(p为质数)。

Sequence

 HDU - 5667 

        Holion August will eat every thing he has found. 

        Now there are many foods,but he does not want to eat all of them at once,so he find a sequence. 

fn=?????1,ab,abfcn1fn2,n=1n=2otherwisefn={1,n=1ab,n=2abfn−1cfn−2,otherwise 

        He gives you 5 numbers n,a,b,c,p,and he will eat fnfn foods.But there are only p foods,so you should tell him fnfn 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. 

    1T10,1n1018,1a,b,c109    1≤T≤10,1≤n≤1018,1≤a,b,c≤109,pp is a prime number,and p109+7p≤109+7.
Output        Output one number for each case,which is fnfn mod p.Sample Input

1
5 3 3 3 233

Sample Output

190

题目思路:先对两边取对数,f(n)=a^b*f(n-1)^c*f(n-2),f(2)=a^b,f(1)=1,可以看出每一项都是一个以a为底的数,我们对递推公式两边取log a,变成g(n)=b+c*g(n-1)+g(n-2),然后就可以构造矩阵了;
[ g(n-1),g(n-2),1]*A=[g(n),g(n-1),1],求矩阵A就可以了;
A=c,1,0
1,0,0
b,0,1
g(n)表示的是指数,[g(n),g(n-1),1] = [g(2),g(1),1]*A^(n-2),我们只需要g(n),在求A^(n-2)时用到快速幂,由于g(n)是指数,而且mod是素数( a^g(n) )%mod =a^(g(n)%(mod-1))%mod,费马小定理!!!!然后单独考虑n=1,2的情况,f(1)=1,f(2)=a^b,直接快速幂;

  1 #include <set>
  2 #include <map>
  3 #include <stack>
  4 #include <queue>
  5 #include <math.h>
  6 #include <vector>
  7 #include <string>
  8 #include <utility>
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12 #include <iostream>
 13 #include <algorithm>
 14 #include <functional>
 15  
 16 using namespace std;
 17 struct Matrax{
 18     long long m[10][10];
 19 }ter;
 20 long long mod;
 21 Matrax muli(Matrax a,Matrax b){
 22     Matrax p;
 23     for(int i=0;i<3;i++)
 24     for(int j=0;j<3;j++){
 25         p.m[i][j]=0;
 26         for(int k=0;k<3;k++){
 27             p.m[i][j]+=(a.m[i][k]*b.m[k][j])%(mod-1);
 28             p.m[i][j]%=mod-1;
 29         }
 30     }
 31     return p;
 32 }//矩阵乘法
 33 Matrax quick_mod(Matrax a,long long b){
 34     Matrax ans=ter;
 35     while(b){
 36         if(b&1){
 37             ans=muli(ans,a);
 38             b--;
 39         }
 40         else {
 41             b>>=1;
 42             a=muli(a,a);
 43         }
 44     }
 45     return ans;
 46 }//快速幂
 47 long long qmod(long long a,long long b){
 48     long long ans=1;
 49     while(b){
 50         if(b&1){
 51             ans=ans*a%mod;
 52             b--;
 53         }
 54         b>>=1;
 55         a=a*a%mod;
 56     }
 57     return ans;
 58 }
 59 int main(){
 60     int t;
 61     scanf("%d",&t);
 62     while(t--){
 63         long long n,a,b,c;
 64         scanf("%I64d%I64d%I64d%I64d%I64d",&n,&a,&b,&c,&mod);
 65         if(n==1){
 66             puts("1");
 67             continue;
 68         }
 69         if(n==2){
 70             printf("%I64d
",qmod(a,b));
 71             continue;
 72         }
 73         ter.m[0][0]=1;
 74         ter.m[0][1]=0;
 75         ter.m[0][2]=0;
 76         ter.m[1][0]=0;
 77         ter.m[1][1]=1;
 78         ter.m[1][2]=0;
 79         ter.m[2][0]=0;
 80         ter.m[2][1]=0;
 81         ter.m[2][2]=1;//初始化E矩阵   因为本题推出来是三元相加,所以用三维矩阵
 82         n-=2;
 83         Matrax A,B;
 84         A.m[0][0]=0;
 85         A.m[0][1]=1;
 86         A.m[0][2]=0;
 87         A.m[1][0]=1;
 88         A.m[1][1]=c;
 89         A.m[1][2]=0;
 90         A.m[2][0]=0;
 91         A.m[2][1]=b;
 92         A.m[2][2]=1;//这里是中间连乘部分的矩阵
 93         A=quick_mod(A,n);
 94         B.m[0][0]=0;
 95         B.m[0][1]=b;
 96         B.m[0][2]=1;
 97         B.m[1][0]=0;
 98         B.m[1][1]=0;
 99         B.m[1][2]=0;
100         B.m[2][0]=0;
101         B.m[2][1]=0;
102         B.m[2][2]=0;
103         B=muli(B,A);//这里是最初始的矩阵
104 //        cout<<B.m[0][1]<<endl;
105 //        cout<<a<<endl;
106         printf("%I64d
",qmod(a,B.m[0][1]+mod-1));
107     }
108     return 0;
109 }

 

以上是关于HDU5667——费马小定理的主要内容,如果未能解决你的问题,请参考以下文章

题解报告:hdu 6440 Dream(费马小定理+构造)

HDU4869:Turn the pokers(费马小定理+高速幂)

hdu1098费马小定理

hdu4549矩阵快速幂+费马小定理

HDU - 6440(费马小定理)

HDU - 1576(费马小定理求逆元)