zoukankan      html  css  js  c++  java
  • HDU 5667 Sequence 矩阵快速幂

    官方题解:

    观察递推式我们可以发现,所有的fi​​都是a的幂次,所以我们可以对fi​​取一个以a为底的log,gi​​=loga​​ fi​​

    那么递推式变gi​​=b+cgi1​​+gi2​​,这个式子可以矩阵乘法

    这题有一个小trick,注意a mod p=0的情况.

    分析:排除了a mod p=0的情况,幂次可以对(p-1)取模,这是由于离散对数定理

             相关定理请查阅 算导

    吐槽:比赛的时候就是被a mod p=0这种情况给hack掉了,我太弱了

     

    #include <stdio.h>
    #include <iostream>
    #include <vector>
    #include <math.h>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <string.h>
    #include <string>
    using namespace std;
    typedef long long LL;
    const int INF=0x3f3f3f3f;
    const int N=1e5+5;
    LL p,a,b,c,n;
    struct asd{
       LL c[4][4];
    };
    asd mul(asd a,asd b){
        asd d;
        for(int i=1;i<=3;++i){
          for(int j=1;j<=3;++j){
            d.c[i][j]=0;
            for(int k=1;k<=3;++k)
              d.c[i][j]=(d.c[i][j]+a.c[i][k]*b.c[k][j]%(p-1))%(p-1);
          }  
        }
        return d;   
    }
    asd fun(LL m){
        asd a,e;
        for(int i=1;i<=3;++i)
         for(int j=1;j<=3;++j)
           a.c[i][j]=e.c[i][j]=0; 
        a.c[1][1]=c;
        a.c[1][2]=1;
        a.c[1][3]=b;
        a.c[2][1]=1;
        a.c[3][3]=1;
        e.c[1][1]=e.c[2][2]=e.c[3][3]=1;
        while(m){
            if(m&1)e=mul(e,a);
            m>>=1;
            a=mul(a,a);
        }
        return e;   
    }
    LL fun2(LL a,LL x){
        LL res=1;
        while(x){
            if(x&1)res=(res*a)%p;
            x>>=1;
            a=(a*a)%p;
        }
        return res;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--){
          scanf("%I64d%I64d%I64d%I64d%I64d",&n,&a,&b,&c,&p);
          if(n==1){
            printf("1
    ");
            continue;
          }
          if(n==2){
             printf("%I64d
    ",fun2(a,b));
             continue;
          }
          if(a%p==0){
            printf("0
    ");
            continue;
         }
          asd t=fun(n-2);
          LL x=0;
          x=(x+t.c[1][1]*b%(p-1))%(p-1);
          x=(x+t.c[1][3])%(p-1);
          printf("%I64d
    ",fun2(a,x));
        }
        return 0;
    }
    View Code

     

     

  • 相关阅读:
    Binder之启动ServiceManager
    CameraMetaData
    Android JNI 使用的数据结构JNINativeMethod详解
    CameraCaptureSession
    深入理解Android相机体系结构之3---相机服务层
    Camera Service
    Camera相关代码路径
    Android打开ALOGV日志
    深度学习高分辨率遥感影像语义分割
    全自动Landsat影像温度反演软件开发
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5400472.html
Copyright © 2011-2022 走看看