• BZOJ_5118_Fib数列2_矩阵乘法+欧拉定理


    BZOJ_5118_Fib数列2_矩阵乘法+欧拉定理

    Description

    Fib定义为Fib(0)=0,Fib(1)=1,对于n≥2,Fib(n)=Fib(n-1)+Fib(n-2)
    现给出N,求Fib(2^n).

    Input

    本题有多组数据。第一行一个整数T,表示数据组数。
    接下来T行每行一个整数N,含义如题目所示。
    n≤10^15, T≤5

    Output

    输出共T行,每行一个整数为所求答案。
    由于答案可能过大,请将答案mod 1125899839733759后输出

    Sample Input

    2
    2
    31

    Sample Output

    3
    343812777493853

    根据欧拉定理,有$a^{n}modp=a^{nmodvarphi(p)}modp$。
    然后矩阵乘法即可。需要用到快速乘
     
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll p=1125899839733759ll;
    ll n;
    ll qc(ll x,ll y,ll mod) {
        ll re=0;
        for(;y;y>>=1ll,x=(x+x)%mod) if(y&1ll) re=(re+x)%mod;
        return re;
    }
    ll qp(ll x,ll y,ll mod) {
        ll re=1;
        for(;y;y>>=1ll,x=qc(x,x,mod)) if(y&1ll) re=qc(re,x,mod);
        return re;
    }
    struct Mat {
        ll v[2][2];
        Mat() {memset(v,0,sizeof(v));}
        Mat operator * (const Mat &x) const {
            Mat re; int i,j,k;
            for(i=0;i<2;i++) {
                for(j=0;j<2;j++) {
                    for(k=0;k<2;k++) {
                        (re.v[i][j]+=qc(v[i][k],x.v[k][j],p))%=p;
                    }
                }
            }
            return re;
        }
    };
    Mat pow(Mat &x,ll y) {
        Mat I;
        I.v[0][0]=I.v[1][1]=1;
        while(y) {
            if(y&1ll) I=I*x;
            x=x*x;
            y>>=1ll;
        }
        return I;
    }
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%lld",&n);
            n=qp(2,n,p-1);
            Mat x;
            x.v[0][1]=x.v[1][0]=x.v[1][1]=1;
            Mat T=pow(x,n);
            printf("%lld
    ",T.v[1][0]);
        }
    }
    
  • 相关阅读:
    luoguP3181 [HAOI2016]找相同字符
    luoguP4248 [AHOI2013]差异
    luoguP2852 [USACO06DEC]Milk Patterns
    后缀自动机
    luoguP3975 [TJOI2015]弦论
    luoguP2824 [HEOI2016/TJOI2016]排序(线段树分裂做法)
    组合数学学习笔记
    「题解」:[BZOJ2938]病毒 (AC自动机+dfs)
    Linux新人报到
    指针学习笔记
  • 原文地址:https://www.cnblogs.com/suika/p/9062752.html
Copyright © 2020-2023  润新知