zoukankan      html  css  js  c++  java
  • bzoj5118: Fib数列2(费马小定理+矩阵快速幂)

      题目大意:求$fib(2^n)$

      就是求fib矩阵的(2^n)次方%p,p是质数,根据费马小定理有

      注意因为模数比较大会爆LL,得写快速乘法...

    #include<bits/stdc++.h>
    #define ll long long
    #define MOD(x) ((x)>=mod?(x-mod):(x))
    using namespace std;
    const int maxn=500010;
    const ll mod=1125899839733759;
    struct mtx{ll mp[2][2];mtx(){memset(mp, 0, sizeof(mp));}}ans, base;
    ll n, T;
    inline ll mul(ll a, ll b, ll mod)
    {
        ll ans=0; a%=mod;
        for(;b;b>>=1, a=MOD(a+a))
        if(b&1) ans=MOD(ans+a);
        return ans;
    }
    mtx operator*(mtx a, mtx b)
    {
        mtx c;
        for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        for(int k=0;k<2;k++)
        c.mp[i][j]=MOD(c.mp[i][j]+mul(a.mp[i][k], b.mp[k][j], mod));
        return c;
    }
    inline ll power(ll a, ll b, ll mod)
    {
        ll ans=1;
        for(;b;b>>=1, a=mul(a, a, mod))
        if(b&1) ans=mul(ans, a, mod);
        return ans;
    }
    inline ll mtx_power(ll b)
    {
        if(!b) return 0; 
        for(;b;b>>=1, base=base*base)
        if(b&1) ans=ans*base;
        return ans.mp[1][0];
    }
    int main()
    {
        scanf("%lld", &T);
        while(T--)
        {
            scanf("%lld", &n);
            ll t=power(2, n, mod-1);
            base.mp[0][0]=base.mp[0][1]=base.mp[1][0]=1; base.mp[1][1]=0;
            ans.mp[0][0]=ans.mp[1][1]=1; ans.mp[1][0]=ans.mp[0][1]=0;
            printf("%lld
    ", mtx_power(t));
        }
    }
    View Code 
  • 相关阅读:
    Linux查看系统版本信息和设置远程终端登录
    Linux环境下安装JDK
    Windows10修改Tomcat服务端口和一台机器部署多个Tomcat
    [转]C#反射-Assembly.Load、LoadFrom与LoadFile进阶
    【转】C# lock的使用
    一个简单的C++程序及说明
    插入排序
    堆排序
    选择排序
    快速排序
  • 原文地址:https://www.cnblogs.com/Sakits/p/8017450.html
Copyright © 2011-2022 走看看