• 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 }
  • 相关阅读:
    Linux 设备驱动开发
    Neat Matrix Library矩阵库
    使用Linux开源组件而不使用Linux的RTOS解决方案embox
    命令行参数解析getopt
    Linux platform 设备
    编写C编译器 、 操作系统方面知识
    Embassy/Rust 和 FreeRTOS/C的速度比较
    SysAK 应用抖动诊断篇—— eBPF又立功了! | 龙蜥技术
    做ToB软件质量保障的这两年
    PolarDBX迎来开源后首个重大版本升级,2.1版本新增5大特色功能
  • 原文地址:https://www.cnblogs.com/Mingusu/p/12445358.html
Copyright © 2020-2023  润新知