• BZOJ5118:Fib数列2(O1快速模)


    题意:输入N,输出fib(2^N)%1125899839733759。(P=1125899839733759是素数)

    思路:欧拉降幂,因为可以表示为矩阵乘法,2^N在幂的位置,矩阵乘法也可以降幂,所以有ans=a*base^num; num=2^N%(P-1)。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const ll Mod=1125899839733759;
    inline ll mul(ll x,ll y,ll p){
      return ((x*y-(ll)(((long double)x*y+0.5)/p)*p)%p+p)%p;
    }
    struct mat
    {
        ll M[3][3];
        mat() { memset(M,0,sizeof(M)); }
        mat friend operator *(mat a,mat b)
        {
            mat res;
            for(int k=1;k<=2;k++)
             for(int i=1;i<=2;i++)
              for(int j=1;j<=2;j++)
               res.M[i][j]=(res.M[i][j]+mul(a.M[i][k],b.M[k][j],Mod))%Mod;
            return res;
        }
        mat friend operator ^(mat a,ll x)
        {
           mat res; res.M[1][1]=res.M[2][2]=1LL;
           while(x){
              if(x&1LL) res=res*a; a=a*a; x/=2;
           } return res;
        }
    };
    ll qpow(ll a,ll x,ll p){
        ll res=1; while(x){
            if(x&1LL) res=mul(res,a,p);
            a=mul(a,a,p); x/=2;
        } return res;
    }
    int main()
    {
        int T; ll N,num;
        scanf("%d",&T);
        while(T--){
            scanf("%lld",&N);
            num=qpow(2LL,N,Mod-1);
            num--; if(num<0) num+=Mod-1;
            mat base,a;
            base.M[1][1]=base.M[1][2]=base.M[2][1]=1LL; a.M[1][1]=1LL;
            base=base^num;
            a=base*a;
            printf("%lld
    ",a.M[1][1]);
        }
        return 0;
    }
  • 相关阅读:
    四则运算题目生成器
    个人博客作业Week1
    M1/M2项目阶段总结
    个人博客作业week7
    个人博客作业—2
    第一周个人博客作业
    关于生成四则运算式
    个人博客作业week7
    第二次博客作业
    关于webservice大数据量传输时的压缩和解压缩
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9669206.html
Copyright © 2020-2023  润新知